home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / util / misc / Fudgit233.lha / Source / src / readline / readline.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-14  |  143.2 KB  |  5,994 lines

  1. /* readline.c -- a general facility for reading lines of input
  2.    with emacs style editing and completion. */
  3.  
  4. /* Copyright (C) 1987,1989 Free Software Foundation, Inc.
  5.  
  6.    This file contains the Readline Library (the Library), a set of
  7.    routines for providing Emacs style line input to programs that ask
  8.    for it.
  9.  
  10.    The Library is free software; you can redistribute it and/or modify
  11.    it under the terms of the GNU General Public License as published by
  12.    the Free Software Foundation; either version 1, or (at your option)
  13.    any later version.
  14.  
  15.    The Library is distributed in the hope that it will be useful, but
  16.    WITHOUT ANY WARRANTY; without even the implied warranty of
  17.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18.    General Public License for more details.
  19.  
  20.    The GNU General Public License is often shipped with GNU software, and
  21.    is generally kept in a file called COPYING or LICENSE.  If you do not
  22.    have a copy of the license, write to the Free Software Foundation,
  23.    675 Mass Ave, Cambridge, MA 02139, USA. */
  24.  
  25.  
  26. /* Remove these declarations when we have a complete libgnu.a. */
  27. #define STATIC_MALLOC
  28. #ifndef STATIC_MALLOC
  29. extern char *xmalloc (int), *xrealloc (void *, int);
  30. #else
  31. static char *xmalloc (int ), *xrealloc (void *, int );
  32. #endif
  33.  
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <sys/types.h>
  37. #include <fcntl.h>
  38. #include <sys/file.h>
  39. #include <signal.h>
  40.  
  41. #ifdef __GNUC__
  42. #define alloca __builtin_alloca
  43. #else
  44. #if defined (sparc) || defined (sgi)
  45. #include <alloca.h>
  46. #endif
  47. #endif
  48.  
  49. #ifndef NOSTDLIB_H
  50. #include <stdlib.h>
  51. #endif
  52.  
  53. #ifndef NOUNISTD_H
  54. #include <unistd.h>
  55. #endif
  56.  
  57. #define NEW_TTY_DRIVER
  58. #define HAVE_BSD_SIGNALS
  59.  
  60. /* Some USG machines have BSD signal handling (sigblock, sigsetmask, etc.) */
  61. #if defined (USG) && !defined (sgi)
  62. #undef HAVE_BSD_SIGNALS
  63. #endif
  64. /* A patch for AIX which fits nowhere */
  65. #ifdef AIX
  66. #undef HAVE_BSD_SIGNALS
  67. #endif
  68.  
  69. /* System V machines use termio. */
  70. #if !defined (_POSIX_VERSION)
  71. #if defined (USG) || defined (Xenix) || defined (sgi) || defined (DGUX)
  72. #undef NEW_TTY_DRIVER
  73. #include <termio.h>
  74.  
  75. #if !defined (TCOON)
  76. #define TCOON 1
  77. #endif
  78.  
  79. #endif /* USG | Xenix | sgi | DUGX */
  80. #endif /* !_POSIX_VERSION */
  81.  
  82. /* Posix systems use termios. */
  83. #if defined (_POSIX_VERSION)
  84. #undef NEW_TTY_DRIVER
  85. #include <termios.h>
  86. #ifdef HPUX
  87. #include <termio.h>
  88. #endif
  89. #if !defined (O_NDELAY)
  90. #define O_NDELAY O_NONBLOCK    /* Posix-style non-blocking i/o */
  91. #endif /* O_NDELAY */
  92. #endif
  93.  
  94. /* Other (BSD) machines use sgtty. */
  95. #if defined (NEW_TTY_DRIVER)
  96. #include <sgtty.h>
  97. #endif
  98.  
  99. #include <errno.h>
  100. extern int errno;
  101.  
  102. #include <setjmp.h>
  103. #include <sys/stat.h>
  104.  
  105. /* These next are for filename completion.  Perhaps this belongs
  106.    in a different place. */
  107. #include <pwd.h>
  108.  
  109. #if defined (HPUX)
  110. extern struct passwd *getpwent (void);
  111. #endif
  112.  
  113. extern int ioctl (int , int , ...);
  114.  
  115. /* #define HACK_TERMCAP_MOTION */
  116.  
  117. #if !defined (USG) && !defined(HPUX)
  118. #include <sys/dir.h>
  119. #ifdef AIX
  120. #define direct dirent
  121. #endif
  122. #else  /* USG */
  123. #if defined (Xenix)
  124. #include <sys/ndir.h>
  125. #else
  126. #ifdef HPUX
  127. #include <ndir.h>
  128. #else
  129. #include <dirent.h>
  130. #define direct dirent
  131. #define d_namlen d_reclen
  132. #endif  /* HPUX */
  133. #endif  /* Xenix */
  134. #endif  /* USG */
  135.  
  136. #if defined (USG) && defined (TIOCGWINSZ) && !defined (HPUX)
  137. #include <sys/stream.h>
  138. #  if defined (USGr4) || defined (USGr3)
  139. #    include <sys/ptem.h>
  140. #  endif /* USGr4 */
  141. #endif /* USG && TIOCGWINSZ */
  142.  
  143. /* Some standard library routines. */
  144. #include "readline.h"
  145. #include "history.h"
  146.  
  147. #ifndef digit
  148. #define digit(c)  ((c) >= '0' && (c) <= '9')
  149. #endif
  150.  
  151. #ifndef isletter
  152. #define isletter(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
  153. #endif
  154.  
  155. #ifndef digit_value
  156. #define digit_value(c) ((c) - '0')
  157. #endif
  158.  
  159. #ifndef member
  160. char *index (const char *, int);
  161. #define member(c, s) ((c) ? index ((s), (c)) : 0)
  162. #endif
  163.  
  164. #ifndef isident
  165. #define isident(c) ((isletter(c) || digit(c) || c == '_'))
  166. #endif
  167.  
  168. #ifndef exchange
  169. #define exchange(x, y) {int temp = x; x = y; y = temp;}
  170. #endif
  171.  
  172. static void update_line (register char *old, register char *new, int current_line);
  173. static void output_character_function (int );
  174. static void delete_chars (int );
  175. static void insert_some_chars (char *, int );
  176. static int next_macro_key (void);
  177. static void with_macro_input (char *);
  178. static char *filename_completion_function (char *, int , int );
  179.  
  180. #ifdef VOID_SIGHANDLER
  181. #define sighandler void
  182. #else
  183. #define sighandler int
  184. #endif
  185.  
  186. /* This typedef is equivalent to the one for Function; it allows us
  187.    to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
  188. #ifdef SIGHANDLER_1
  189. /*
  190.  HPUX type:
  191.  void (*signal(int sig, void (*action)(int)))(int);
  192. */
  193. typedef sighandler SigHandler (int);
  194. #else
  195. typedef sighandler SigHandler (int, int, struct sigcontext *);
  196. #endif
  197.  
  198. /* If on, then readline handles signals in a way that doesn't screw. */
  199. #define HANDLE_SIGNALS
  200.  
  201.  
  202.  
  203. /* **************************************************************** */
  204. /*                                    */
  205. /*            Line editing input utility            */
  206. /*                                    */
  207. /* **************************************************************** */
  208.  
  209. /* A pointer to the keymap that is currently in use.
  210.    By default, it is the standard emacs keymap. */
  211. Keymap keymap = emacs_standard_keymap;
  212.  
  213. #define vi_mode 0
  214. #define emacs_mode 1
  215.  
  216. /* The current style of editing. */
  217. int rl_editing_mode = emacs_mode;
  218.  
  219. /* Non-zero if the previous command was a kill command. */
  220. static int last_command_was_kill = 0;
  221.  
  222. /* The current value of the numeric argument specified by the user. */
  223. int rl_numeric_arg = 1;
  224.  
  225. /* Non-zero if an argument was typed. */
  226. int rl_explicit_arg = 0;
  227.  
  228. /* Temporary value used while generating the argument. */
  229. static int arg_sign = 1;
  230.  
  231. /* Non-zero means we have been called at least once before. */
  232. static int rl_initialized = 0;
  233.  
  234. /* If non-zero, this program is running in an EMACS buffer. */
  235. static char *running_in_emacs = (char *)NULL;
  236.  
  237. /* The current offset in the current input line. */
  238. int rl_point;
  239.  
  240. /* Mark in the current input line. */
  241. int rl_mark;
  242.  
  243. /* Length of the current input line. */
  244. int rl_end;
  245.  
  246. /* Make this non-zero to return the current input_line. */
  247. int rl_done;
  248.  
  249. /* The last function executed by readline. */
  250. KFunction *rl_last_func = (KFunction *)NULL;
  251.  
  252. /* Top level environment for readline_internal (). */
  253. static jmp_buf readline_top_level;
  254.  
  255. /* The streams we interact with. */
  256. static FILE *in_stream, *out_stream;
  257.  
  258. /* The names of the streams that we do input and output to. */
  259. #ifdef AMIGA
  260. FILE *rl_instream;
  261. FILE *rl_outstream;
  262. #else
  263. FILE *rl_instream = stdin, *rl_outstream = stdout;
  264. #endif
  265.  
  266. /* Non-zero means echo characters as they are read. */
  267. int readline_echoing_p = 1;
  268.  
  269. /* Current prompt. */
  270. char *rl_prompt;
  271.  
  272. /* The number of characters read in order to type this complete command. */
  273. int rl_key_sequence_length = 0;
  274.  
  275. /* If non-zero, then this is the address of a function to call just
  276.    before readline_internal () prints the first prompt. */
  277. VFunction *rl_startup_hook = (VFunction *)NULL;
  278.  
  279. /* If non-zero, then this is the address of a function to call when
  280.    completing on a directory name.  The function is called with
  281.    the address of a string (the current directory name) as an arg. */
  282. CCFunction *rl_symbolic_link_hook = (CCFunction *)NULL;
  283.  
  284. /* What we use internally.  You should always refer to RL_LINE_BUFFER. */
  285. static char *the_line;
  286.  
  287. /* The character that can generate an EOF.  Really read from
  288.    the terminal driver... just defaulted here. */
  289. static int eof_char = CTRL ('D');
  290.  
  291. /* Non-zero makes this the next keystroke to read. */
  292. int rl_pending_input = 0;
  293.  
  294. /* Pointer to a useful terminal name. */
  295. char *rl_terminal_name = (char *)NULL;
  296.  
  297. /* Line buffer and maintenence. */
  298. char *rl_line_buffer = (char *)NULL;
  299. static int rl_line_buffer_len = 0;
  300. #define DEFAULT_BUFFER_SIZE 256
  301.  
  302.  
  303. /* **************************************************************** */
  304. /*                                    */
  305. /*            `Forward' declarations              */
  306. /*                                    */
  307. /* **************************************************************** */
  308.  
  309. /* Non-zero means do not parse any lines other than comments and
  310.    parser directives. */
  311. static unsigned char parsing_conditionalized_out = 0;
  312.  
  313. /* Caseless strcmp (). */
  314. static int stricmp (char *, char *), strnicmp (char *, char *, int );
  315.  
  316. /* Non-zero means to save keys that we dispatch on in a kbd macro. */
  317. static int defining_kbd_macro = 0;
  318.  
  319.  
  320. /* **************************************************************** */
  321. /*                                    */
  322. /*            Top Level Functions                */
  323. /*                                    */
  324. /* **************************************************************** */
  325.  
  326. /* Read a line of input.  Prompt with PROMPT.  A NULL PROMPT means
  327.    none.  A return value of NULL means that EOF was encountered. */
  328.  
  329. void rl_initialize (void);
  330. void rl_on_new_line (void);
  331. void rl_redisplay (void);
  332. void rl_init_argument (void);
  333. int rl_read_key (void);
  334. void rl_dispatch (register int key, Keymap map);
  335. void free_undo_list (void);
  336. void rl_reset_terminal (char *terminal_name);
  337. void rl_clear_message (void);
  338. void rl_clean_up_for_exit (void);
  339. void crlf (void);
  340. void rl_forced_update_display (void);
  341. int rl_getc (FILE *);
  342. void readline_initialize_everything (void);
  343. void init_terminal_io (char *);
  344. void readline_default_bindings (void);
  345. int rl_read_init_file (char *);
  346. void rl_digit_loop (void);
  347. void rl_message (char *, int , int );
  348. int numeric (int c);
  349. void move_vert (int );
  350. void clear_to_eol (int );
  351. void backspace (int );
  352. void rl_add_undo (enum undo_code , int , int , char *);
  353. void rl_kill_text (int , int );
  354. void rl_change_case (int , int );
  355. void rl_modifying (int , int );
  356. void rl_begin_undo_group (void);
  357. void rl_end_undo_group (void);
  358. void rl_complete_internal (int );
  359. extern void free (void *);
  360. #ifdef NOUNISTD_H
  361. extern int getpid (void);
  362. extern int read (int, void *, unsigned int);
  363. #endif
  364. #ifdef NOSTDLIB_H
  365. extern char *getenv (const char *);
  366. extern void qsort (void *, size_t, size_t,
  367.     int (*) (const void *, const void *));
  368. extern void abort (void);
  369. #endif
  370. extern void rl_initialize_funmap (void);
  371. extern int tputs (char *, int, void (*) (int));
  372. extern int tgetent (char *, char *);
  373. extern int tgetnum (char *);
  374. void rl_search_history (int direction, int invoking_key);
  375. void rl_execute_next (int c);
  376. int rl_bind_key (int key, KFunction (*function));
  377. extern int rl_add_funmap_entry (char *name, KFunction (*function));
  378. void rl_generic_bind (int type, char *keyseq, char *data, Keymap map);
  379. int rl_translate_keyseq (char *, char *, int *);
  380. extern int close (int);
  381. void rl_parse_and_bind (char *);
  382. void rl_variable_bind (char *, char *);
  383. int glean_key_from_name (char *);
  384. extern void *realloc (void *, size_t);
  385. static void rl_prep_terminal (void), rl_deprep_terminal (void);
  386. static char *readline_internal (void);
  387. static void start_using_history (void);
  388. static void rl_set_signals (void);
  389. static void rl_clear_signals (void);
  390. static void free_history_entry (HIST_ENTRY *);
  391. KFunction *rl_named_function (char *);
  392.  
  393. char *
  394. rl_readline (char *prompt)
  395. {
  396.   char *value;
  397.  
  398.   rl_prompt = prompt;
  399.  
  400.   /* If we are at EOF return a NULL string. */
  401.   if (rl_pending_input == EOF)
  402.     {
  403.       rl_pending_input = 0;
  404.       return ((char *)NULL);
  405.     }
  406.  
  407.   rl_initialize ();
  408.   rl_prep_terminal ();
  409.  
  410. #ifdef HANDLE_SIGNALS
  411.   rl_set_signals ();
  412. #endif
  413.  
  414.   value = readline_internal ();
  415.   rl_deprep_terminal ();
  416.  
  417. #ifdef HANDLE_SIGNALS
  418.   rl_clear_signals ();
  419. #endif
  420.  
  421.   return (value);
  422. }
  423.  
  424. /* Read a line of input from the global rl_instream, doing output on
  425.    the global rl_outstream.
  426.    If rl_prompt is non-null, then that is our prompt. */
  427. static char *
  428. readline_internal (void)
  429. {
  430.   int lastc, c, eof_found;
  431.  
  432.   in_stream = rl_instream; out_stream = rl_outstream;
  433.   lastc = eof_found = 0;
  434.  
  435.   if (rl_startup_hook)
  436.     (*rl_startup_hook) (0);
  437.  
  438.   if (!readline_echoing_p) {
  439.       if (rl_prompt) {
  440.        fprintf (out_stream, "%s", rl_prompt);
  441.        fflush (out_stream);
  442.       }
  443.   }
  444.   else {
  445.       rl_on_new_line ();
  446.       rl_redisplay ();
  447. #ifdef VI_MODE
  448.       if (rl_editing_mode == vi_mode)
  449.     rl_vi_insertion_mode (0, 0);
  450. #endif /* VI_MODE */
  451.   }
  452.  
  453.   while (!rl_done) {
  454.       int lk = last_command_was_kill;
  455.       int code = setjmp (readline_top_level);
  456.  
  457.       if (code)
  458.         rl_redisplay ();
  459.  
  460.       if (!rl_pending_input) {
  461.       /* Then initialize the argument and number of keys read. */
  462.         rl_init_argument ();
  463.         rl_key_sequence_length = 0;
  464.       }
  465.  
  466.       c = rl_read_key ();
  467.  
  468.       /* EOF typed to a non-blank line is a <NL>. */
  469.       if (c == EOF && rl_end)
  470.          c = NEWLINE;
  471.  
  472.       /* The character eof_char typed to blank line, and not as the
  473.      previous character is interpreted as EOF. */
  474.       if (((c == eof_char && lastc != c) || c == EOF) && !rl_end) {
  475.          eof_found = 1;
  476.          break;
  477.       }
  478.  
  479.       lastc = c;
  480.       rl_dispatch (c, keymap);
  481.  
  482.       /* If there was no change in last_command_was_kill, then no kill
  483.      has taken place.  Note that if input is pending we are reading
  484.      a prefix command, so nothing has changed yet. */
  485.       if (!rl_pending_input) {
  486.         if (lk == last_command_was_kill)
  487.           last_command_was_kill = 0;
  488.       }
  489.  
  490. #ifdef VI_MODE
  491.       /* In vi mode, when you exit insert mode, the cursor moves back
  492.      over the previous character.  We explicitly check for that here. */
  493.       if (rl_editing_mode == vi_mode && keymap == vi_movement_keymap)
  494.     rl_vi_check ();
  495. #endif
  496.  
  497.       if (!rl_done)
  498.         rl_redisplay ();
  499.   }
  500.  
  501.   /* Restore the original of this history line, iff the line that we
  502.      are editing was originally in the history, AND the line has changed. */
  503.   {
  504.     HIST_ENTRY *entry = hl_current_history ();
  505.  
  506.     if (entry && rl_undo_list) {
  507.        char *temp = savestring (the_line);
  508.        rl_revert_line (0, 0);
  509.        entry = hl_replace_history_entry (hl_where_history (), the_line,
  510.                        (char *)NULL);
  511.        free_history_entry (entry);
  512.  
  513.        strcpy (the_line, temp);
  514.        free (temp);
  515.     }
  516.   }
  517.  
  518.   /* At any rate, it is highly likely that this line has an undo list.  Get
  519.      rid of it now. */
  520.   if (rl_undo_list)
  521.     free_undo_list ();
  522.  
  523.   if (eof_found)
  524.     return (char *)NULL;
  525.   else
  526.     return (savestring (the_line));
  527. }
  528.  
  529.  
  530. /* **************************************************************** */
  531. /*                                        */
  532. /*               Signal Handling                          */
  533. /*                                    */
  534. /* **************************************************************** */
  535.  
  536. #ifdef SIGWINCH
  537. static SigHandler *old_sigwinch = (SigHandler *)NULL;
  538.  
  539. static sighandler
  540. rl_handle_sigwinch (int sig
  541. #ifndef SIGHANDLER_1
  542. , int code, struct sigcontext *scp
  543. #endif
  544. )
  545. {
  546.   char *term = rl_terminal_name, *getenv (const char *);
  547.  
  548.   if (readline_echoing_p)
  549.     {
  550.       if (!term)
  551.         term = getenv ("TERM");
  552.       if (!term)
  553.         term = "dumb";
  554.       rl_reset_terminal (term);
  555. #ifdef NEVER
  556.       crlf ();
  557.       rl_forced_update_display ();
  558. #endif
  559.     }
  560.  
  561.   if (old_sigwinch &&
  562.       old_sigwinch != (SigHandler *)SIG_IGN &&
  563.       old_sigwinch != (SigHandler *)SIG_DFL)
  564.     (*old_sigwinch)(sig
  565. #ifndef SIGHANDLER_1
  566.     , code, scp
  567. #endif
  568.     );
  569. #ifndef VOID_SIGHANDLER
  570.     return(0);
  571. #endif
  572. }
  573. #endif  /* SIGWINCH */
  574.  
  575. #ifdef HANDLE_SIGNALS
  576. /* Interrupt handling. */
  577. static SigHandler *old_int  = (SigHandler *)NULL,
  578.           *old_tstp = (SigHandler *)NULL,
  579.           *old_ttou = (SigHandler *)NULL,
  580.           *old_ttin = (SigHandler *)NULL;
  581.           /*  *old_cont = (SigHandler *)NULL; */
  582.  
  583. /* Handle an interrupt character. */
  584. static sighandler
  585. rl_signal_handler (int sig
  586. #ifndef SIGHANDLER_1
  587. , int code, struct sigcontext *scp
  588. #endif
  589. )
  590. {
  591. #if !defined (HAVE_BSD_SIGNALS)
  592.   /* Since the signal will not be blocked while we are in the signal
  593.      handler, ignore it until rl_clear_signals resets the catcher. */
  594.   if (sig == SIGINT)
  595.     signal (sig, SIG_IGN);
  596. #endif /* !HAVE_BSD_SIGNALS */
  597.  
  598.   switch (sig)
  599.     {
  600.     case SIGINT:
  601.       free_undo_list ();
  602.       rl_clear_message ();
  603.       rl_init_argument ();
  604.  
  605. #ifdef SIGTSTP
  606.     case SIGTSTP:
  607.     case SIGTTOU:
  608.     case SIGTTIN:
  609. #endif
  610.  
  611.       rl_clean_up_for_exit ();
  612.       rl_deprep_terminal ();
  613.       rl_clear_signals ();
  614.       rl_pending_input = 0;
  615.  
  616.       kill (getpid (), sig);
  617.  
  618. #if defined (_POSIX_VERSION)
  619.     {
  620.     sigset_t ssset;
  621.  
  622.     sigemptyset (&ssset);
  623.     sigprocmask (SIG_SETMASK, &ssset, (sigset_t *)NULL);
  624.     }
  625. #else
  626. #if defined (HAVE_BSD_SIGNALS)
  627.       sigsetmask (0);
  628. #endif /* HAVE_BSD_SIGNALS */
  629. #endif /* _POSIX_VERSION */
  630.  
  631.       rl_prep_terminal ();
  632.       rl_set_signals ();
  633. #ifdef SIGTSTP
  634.       if (sig == SIGTSTP) {
  635.           crlf ();
  636.           rl_forced_update_display ();
  637.       }
  638. #endif
  639.     }
  640. #ifndef VOID_SIGHANDLER
  641.     return(0);
  642. #endif
  643. }
  644.  
  645. static void rl_set_signals (void)
  646. {
  647.   old_int = (SigHandler *)signal (SIGINT, rl_signal_handler);
  648.   if (old_int == (SigHandler *)SIG_IGN)
  649.     signal (SIGINT, SIG_IGN);
  650.  
  651. #ifdef SIGTSTP
  652.   old_tstp = (SigHandler *)signal (SIGTSTP, rl_signal_handler);
  653.   if (old_tstp == (SigHandler *)SIG_IGN)
  654.     signal (SIGTSTP, SIG_IGN);
  655. #endif
  656. #ifdef SIGTTOU
  657.   old_ttou = (SigHandler *)signal (SIGTTOU, rl_signal_handler);
  658.   old_ttin = (SigHandler *)signal (SIGTTIN, rl_signal_handler);
  659.  
  660.   if (old_tstp == (SigHandler *)SIG_IGN)
  661.     {
  662.       signal (SIGTTOU, SIG_IGN);
  663.       signal (SIGTTIN, SIG_IGN);
  664.     }
  665. #endif
  666.  
  667. #ifdef SIGWINCH
  668.   old_sigwinch = (SigHandler *)signal (SIGWINCH, rl_handle_sigwinch);
  669. #endif
  670. }
  671.  
  672. static void rl_clear_signals (void)
  673. {
  674.   signal (SIGINT, old_int);
  675.  
  676. #ifdef SIGTSTP
  677.   signal (SIGTSTP, old_tstp);
  678. #endif
  679.  
  680. #ifdef SIGTTOU
  681.   signal (SIGTTOU, old_ttou);
  682.   signal (SIGTTIN, old_ttin);
  683. #endif
  684.  
  685. #ifdef SIGWINCH
  686.       signal (SIGWINCH, old_sigwinch);
  687. #endif
  688. }
  689. #endif  /* HANDLE_SIGNALS */
  690.  
  691.  
  692. /* **************************************************************** */
  693. /*                                    */
  694. /*            Character Input Buffering               */
  695. /*                                    */
  696. /* **************************************************************** */
  697.  
  698. /* If the terminal was in xoff state when we got to it, then xon_char
  699.    contains the character that is supposed to start it again. */
  700. static int xon_char, xoff_state;
  701. static int pop_index = 0, push_index = 0, ibuffer_len = 511;
  702. static unsigned char ibuffer[512];
  703.  
  704. /* Non-null means it is a pointer to a function to run while waiting for
  705.    character input. */
  706. VFunction *rl_event_hook = (VFunction *)NULL;
  707.  
  708. #define any_typein (push_index != pop_index)
  709.  
  710. /* Add KEY to the buffer of characters to be read. */
  711. static void rl_stuff_char (int key)
  712. {
  713.   if (key == EOF)
  714.     {
  715.       key = NEWLINE;
  716.       rl_pending_input = EOF;
  717.     }
  718.   ibuffer[push_index++] = key;
  719.   if (push_index >= ibuffer_len)
  720.     push_index = 0;
  721. }
  722.  
  723. /* Return the amount of space available in the
  724.    buffer for stuffing characters. */
  725. static int
  726. ibuffer_space (void)
  727. {
  728.   if (pop_index > push_index)
  729.     return (pop_index - push_index);
  730.   else
  731.     return (ibuffer_len - (push_index - pop_index));
  732. }
  733.  
  734. /* Get a key from the buffer of characters to be read.
  735.    Return the key in KEY.
  736.    Result is KEY if there was a key, or 0 if there wasn't. */
  737. static int
  738. rl_get_char (int *key)
  739. {
  740.   if (push_index == pop_index)
  741.     return (0);
  742.  
  743.   *key = ibuffer[pop_index++];
  744.  
  745.   if (pop_index >= ibuffer_len)
  746.     pop_index = 0;
  747.  
  748.   return (1);
  749. }
  750.  
  751. /* Stuff KEY into the *front* of the input buffer.
  752.    Returns non-zero if successful, zero if there is
  753.    no space left in the buffer. */
  754. int
  755. rl_unget_char (int key)
  756. {
  757.   if (ibuffer_space ())
  758.     {
  759.       pop_index--;
  760.       if (pop_index < 0)
  761.     pop_index = ibuffer_len - 1;
  762.       ibuffer[pop_index] = key;
  763.       return (1);
  764.     }
  765.   return (0);
  766. }
  767.  
  768. /* If a character is available to be read, then read it
  769.    and stuff it into IBUFFER.  Otherwise, just return. */
  770. void rl_gather_tyi (void)
  771. {
  772.   int tty = fileno (in_stream);
  773.   register int tem, result = -1;
  774.   long chars_avail;
  775.   char input;
  776.  
  777. #ifdef FIONREAD
  778.   result = ioctl (tty, FIONREAD, &chars_avail);
  779. #endif
  780.  
  781.   if (result == -1)
  782.     {
  783.       fcntl (tty, F_SETFL, O_NDELAY);
  784.       chars_avail = read (tty, &input, 1);
  785.       fcntl (tty, F_SETFL, 0);
  786.       if (chars_avail == -1 && errno == EAGAIN)
  787.     return;
  788.     }
  789.  
  790.   /* If there's nothing available, don't waste time trying to read
  791.      something. */
  792.   if (chars_avail == 0)
  793.     return;
  794.  
  795.   tem = ibuffer_space ();
  796.  
  797.   if (chars_avail > tem)
  798.     chars_avail = tem;
  799.  
  800.   /* One cannot read all of the available input.  I can only read a single
  801.      character at a time, or else programs which require input can be
  802.      thwarted.  If the buffer is larger than one character, I lose.
  803.      Damn! */
  804.   if (tem < ibuffer_len)
  805.     chars_avail = 0;
  806.  
  807.   if (result != -1)
  808.     {
  809.       while (chars_avail--)
  810.     rl_stuff_char (rl_getc (in_stream));
  811.     }
  812.   else
  813.     {
  814.       if (chars_avail)
  815.     rl_stuff_char (input);
  816.     }
  817. }
  818.  
  819. /* Read a key, including pending input. */
  820. int
  821. rl_read_key (void)
  822. {
  823.   int c;
  824.  
  825.   rl_key_sequence_length++;
  826.  
  827.   if (rl_pending_input)
  828.     {
  829.       c = rl_pending_input;
  830.       rl_pending_input = 0;
  831.     }
  832.   else
  833.     {
  834.       /* If input is coming from a macro, then use that. */
  835.       if (c = next_macro_key ())
  836.     return (c);
  837.  
  838.       /* If the user has an event function, then call it periodically. */
  839.       if (rl_event_hook)
  840.     {
  841.       while (rl_event_hook && !rl_get_char (&c))
  842.         {
  843.           (*rl_event_hook) (0);
  844.           rl_gather_tyi ();
  845.         }
  846.     }
  847.       else
  848.     {
  849.       if (!rl_get_char (&c))
  850.         c = rl_getc (in_stream);
  851.     }
  852.     }
  853.  
  854. #ifdef NEVER  /* This breaks supdup to 4.0.3c machines. */
  855. #ifdef TIOCSTART
  856.   /* Ugh.  But I can't think of a better way. */
  857.   if (xoff_state && c == xon_char)
  858.     {
  859.       ioctl (fileno (in_stream), TIOCSTART, 0);
  860.       xoff_state = 0;
  861.       return (rl_read_key ());
  862.     }
  863. #endif /* TIOCSTART */
  864. #endif
  865.  
  866.   return (c);
  867. }
  868.  
  869. /* I'm beginning to hate the declaration rules for various compilers. */
  870. static void add_macro_char (int c);
  871.  
  872. /* Do the command associated with KEY in MAP.
  873.    If the associated command is really a keymap, then read
  874.    another key, and dispatch into that map. */
  875. void rl_dispatch (register int key, Keymap map)
  876. {
  877.  
  878.   if (defining_kbd_macro)
  879.     add_macro_char (key);
  880.  
  881.   if (key > 127 && key < 256) {
  882.       if (map[ESC].type == ISKMAP) {
  883.           map = (Keymap)map[ESC].function;
  884.           key -= 128;
  885.           rl_dispatch (key, map);
  886.       }
  887.       else
  888.         ding ();
  889.       return;
  890.   }
  891.  
  892.   switch (map[key].type) {
  893.     case ISFUNC:
  894.       {
  895.           KFunction *func = map[key].function;
  896.  
  897.           if (func != (KFunction *)NULL) {
  898.               /* Special case rl_do_lowercase_version (). */
  899.               if (func == (KFunction *)rl_do_lowercase_version) {
  900.                  rl_dispatch (to_lower (key), map);
  901.                  return;
  902.               }
  903.       
  904.               (*map[key].function)(rl_numeric_arg * arg_sign, key);
  905.       
  906.               /* If we have input pending, then the last command was a prefix
  907.                  command.  Don't change the state of rl_last_func.  Otherwise,
  908.                  remember the last command executed in this variable. */
  909.               if (!rl_pending_input)
  910.                 rl_last_func = map[key].function;
  911.           }
  912.           else {
  913.               rl_abort (0, 0);
  914.               return;
  915.           }
  916.      }
  917.      break;
  918.  
  919.     case ISKMAP:
  920.       if (map[key].function != (KFunction *)NULL) {
  921.          int newkey;
  922.  
  923.          rl_key_sequence_length++;
  924.          newkey = rl_read_key ();
  925.          rl_dispatch (newkey, (Keymap)map[key].function);
  926.       }
  927.       else {
  928.          rl_abort (0, 0);
  929.          return;
  930.       }
  931.       break;
  932.  
  933.     case ISMACR:
  934.       if (map[key].function != (KFunction *)NULL) {
  935.           char *macro = savestring ((char *)map[key].function);
  936.  
  937.           with_macro_input (macro);
  938.           return;
  939.       }
  940.       break;
  941.    }
  942. }
  943.  
  944.  
  945. /* **************************************************************** */
  946. /*                                    */
  947. /*            Hacking Keyboard Macros             */
  948. /*                                    */
  949. /* **************************************************************** */
  950.  
  951. /* The currently executing macro string.  If this is non-zero,
  952.    then it is a malloc ()'ed string where input is coming from. */
  953. static char *executing_macro = (char *)NULL;
  954.  
  955. /* The offset in the above string to the next character to be read. */
  956. static int executing_macro_index = 0;
  957.  
  958. /* The current macro string being built.  Characters get stuffed
  959.    in here by add_macro_char (). */
  960. static char *current_macro = (char *)NULL;
  961.  
  962. /* The size of the buffer allocated to current_macro. */
  963. static int current_macro_size = 0;
  964.  
  965. /* The index at which characters are being added to current_macro. */
  966. static int current_macro_index = 0;
  967.  
  968. /* A structure used to save nested macro strings.
  969.    It is a linked list of string/index for each saved macro. */
  970. struct saved_macro {
  971.   char *str;
  972.   int index;
  973.   struct saved_macro *next;
  974. };
  975.  
  976. /* The list of saved macros. */
  977. struct saved_macro *macro_list = (struct saved_macro *)NULL;
  978.  
  979. /* Forward declarations of static functions.  Thank you C. */
  980. static void push_executing_macro (void), pop_executing_macro (void);
  981.  
  982. /* This one has to be declared earlier in the file. */
  983. /* static void add_macro_char (); */
  984.  
  985. /* Set up to read subsequent input from STRING.
  986.    STRING is free ()'ed when we are done with it. */
  987. static void
  988. with_macro_input (char *string)
  989. {
  990.   push_executing_macro ();
  991.   executing_macro = string;
  992.   executing_macro_index = 0;
  993. }
  994.  
  995. /* Return the next character available from a macro, or 0 if
  996.    there are no macro characters. */
  997. static int
  998. next_macro_key (void)
  999. {
  1000.   if (!executing_macro)
  1001.     return (0);
  1002.  
  1003.   if (!executing_macro[executing_macro_index])
  1004.     {
  1005.       pop_executing_macro ();
  1006.       return (next_macro_key ());
  1007.     }
  1008.  
  1009.   return (executing_macro[executing_macro_index++]);
  1010. }
  1011.  
  1012. /* Save the currently executing macro on a stack of saved macros. */
  1013. static void
  1014. push_executing_macro (void)
  1015. {
  1016.   struct saved_macro *saver;
  1017.  
  1018.   saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro));
  1019.   saver->next = macro_list;
  1020.   saver->index = executing_macro_index;
  1021.   saver->str = executing_macro;
  1022.  
  1023.   macro_list = saver;
  1024. }
  1025.  
  1026. /* Discard the current macro, replacing it with the one
  1027.    on the top of the stack of saved macros. */
  1028. static void
  1029. pop_executing_macro (void)
  1030. {
  1031.   if (executing_macro)
  1032.     free (executing_macro);
  1033.  
  1034.   executing_macro = (char *)NULL;
  1035.   executing_macro_index = 0;
  1036.  
  1037.   if (macro_list)
  1038.     {
  1039.       struct saved_macro *disposer = macro_list;
  1040.  
  1041.       executing_macro = macro_list->str;
  1042.       executing_macro_index = macro_list->index;
  1043.       macro_list = macro_list->next;
  1044.       free (disposer);
  1045.     }
  1046. }
  1047.  
  1048. /* Add a character to the macro being built. */
  1049. static void
  1050. add_macro_char (int c)
  1051. {
  1052.   if (current_macro_index + 1 >= current_macro_size)
  1053.     {
  1054.       if (!current_macro)
  1055.     current_macro = (char *)xmalloc (current_macro_size = 25);
  1056.       else
  1057.     current_macro =
  1058.       (char *)xrealloc (current_macro, current_macro_size += 25);
  1059.     }
  1060.  
  1061.   current_macro[current_macro_index++] = c;
  1062.   current_macro[current_macro_index] = '\0';
  1063. }
  1064.  
  1065. /* Begin defining a keyboard macro.
  1066.    Keystrokes are recorded as they are executed.
  1067.    End the definition with rl_end_kbd_macro ().
  1068.    If a numeric argument was explicitly typed, then append this
  1069.    definition to the end of the existing macro, and start by
  1070.    re-executing the existing macro. */
  1071. void rl_start_kbd_macro (int ignore1, int ignore2)
  1072. {
  1073.   if (defining_kbd_macro)
  1074.     rl_abort (0, 0);
  1075.  
  1076.   if (rl_explicit_arg)
  1077.     {
  1078.       if (current_macro)
  1079.     with_macro_input (savestring (current_macro));
  1080.     }
  1081.   else
  1082.     current_macro_index = 0;
  1083.  
  1084.   defining_kbd_macro = 1;
  1085. }
  1086.  
  1087. /* Stop defining a keyboard macro.
  1088.    A numeric argument says to execute the macro right now,
  1089.    that many times, counting the definition as the first time. */
  1090. void rl_end_kbd_macro (int count, int ignore)
  1091. {
  1092.   if (!defining_kbd_macro)
  1093.     rl_abort (0, 0);
  1094.  
  1095.   current_macro_index -= (rl_key_sequence_length - 1);
  1096.   current_macro[current_macro_index] = '\0';
  1097.  
  1098.   defining_kbd_macro = 0;
  1099.  
  1100.   rl_call_last_kbd_macro (--count, 0);
  1101. }
  1102.  
  1103. /* Execute the most recently defined keyboard macro.
  1104.    COUNT says how many times to execute it. */
  1105. void rl_call_last_kbd_macro (int count, int ignore)
  1106. {
  1107.   if (!current_macro)
  1108.     rl_abort (0, 0);
  1109.  
  1110.   while (count--)
  1111.     with_macro_input (savestring (current_macro));
  1112. }
  1113.  
  1114.  
  1115. /* **************************************************************** */
  1116. /*                                    */
  1117. /*            Initializations                 */
  1118. /*                                    */
  1119. /* **************************************************************** */
  1120.  
  1121. /* Initliaze readline (and terminal if not already). */
  1122. void rl_initialize (void)
  1123. {
  1124.   /* If we have never been called before, initialize the
  1125.      terminal and data structures. */
  1126.   if (!rl_initialized)
  1127.     {
  1128.       readline_initialize_everything ();
  1129.       rl_initialized++;
  1130.     }
  1131.  
  1132.   /* Initalize the current line information. */
  1133.   rl_point = rl_end = 0;
  1134.   the_line = rl_line_buffer;
  1135.   the_line[0] = 0;
  1136.  
  1137.   /* We aren't done yet.  We haven't even gotten started yet! */
  1138.   rl_done = 0;
  1139.  
  1140.   /* Tell the history routines what is going on. */
  1141.   start_using_history ();
  1142.  
  1143.   /* Make the display buffer match the state of the line. */
  1144.   {
  1145.     extern char *rl_display_prompt;
  1146.     extern int forced_display;
  1147.  
  1148.     rl_on_new_line ();
  1149.  
  1150.     rl_display_prompt = rl_prompt ? rl_prompt : "";
  1151.     forced_display = 1;
  1152.   }
  1153.  
  1154.   /* No such function typed yet. */
  1155.   rl_last_func = (KFunction *)NULL;
  1156.  
  1157.   /* Parsing of key-bindings begins in an enabled state. */
  1158.   parsing_conditionalized_out = 0;
  1159. }
  1160.  
  1161. /* Initialize the entire state of the world. */
  1162. void readline_initialize_everything (void)
  1163. {
  1164.   /* Find out if we are running in Emacs. */
  1165.   running_in_emacs = (char *)getenv ("EMACS");
  1166.  
  1167.   /* Allocate data structures. */
  1168.   if (!rl_line_buffer)
  1169.     rl_line_buffer =
  1170.       (char *)xmalloc (rl_line_buffer_len = DEFAULT_BUFFER_SIZE);
  1171.  
  1172.   /* Initialize the terminal interface. */
  1173.   init_terminal_io ((char *)NULL);
  1174.  
  1175.   /* Bind tty characters to readline functions. */
  1176.   readline_default_bindings ();
  1177.  
  1178.   /* Initialize the function names. */
  1179.   rl_initialize_funmap ();
  1180.  
  1181.   /* Read in the init file. */
  1182.   rl_read_init_file ((char *)NULL);
  1183.  
  1184.   /* If the completion parser's default word break characters haven't
  1185.      been set yet, then do so now. */
  1186.   {
  1187.     extern char *rl_completer_word_break_characters;
  1188.     extern char *rl_basic_word_break_characters;
  1189.  
  1190.     if (rl_completer_word_break_characters == (char *)NULL)
  1191.       rl_completer_word_break_characters = rl_basic_word_break_characters;
  1192.   }
  1193. }
  1194.  
  1195. /* If this system allows us to look at the values of the regular
  1196.    input editing characters, then bind them to their readline
  1197.    equivalents. */
  1198. void readline_default_bindings (void)
  1199. {
  1200.  
  1201. #ifdef NEW_TTY_DRIVER
  1202.   struct sgttyb ttybuff;
  1203.   int tty = fileno (rl_instream);
  1204.  
  1205.   if (ioctl (tty, TIOCGETP, &ttybuff) != -1)
  1206.     {
  1207.       int erase = ttybuff.sg_erase, kill = ttybuff.sg_kill;
  1208.  
  1209.       if (erase != -1 && keymap[erase].type == ISFUNC)
  1210.     keymap[erase].function = rl_rubout;
  1211.  
  1212.       if (kill != -1 && keymap[kill].type == ISFUNC)
  1213.     keymap[kill].function = rl_unix_line_discard;
  1214.     }
  1215. #ifdef IOCTL_DEBUG
  1216.   else
  1217.     {
  1218.       fprintf(stderr, "TIOCGETP: %d\n", tty);
  1219.       perror("ioctl");
  1220.     }
  1221. #endif /*IOCTL_DEBUG*/
  1222.  
  1223. #ifdef TIOCGLTC
  1224.   {
  1225.     struct ltchars lt;
  1226.  
  1227.     if (ioctl (tty, TIOCGLTC, <) != -1)
  1228.       {
  1229.     int erase = lt.t_werasc, nextc = lt.t_lnextc;
  1230.  
  1231.     if (erase != -1 && keymap[erase].type == ISFUNC)
  1232.       keymap[erase].function = rl_unix_word_rubout;
  1233.  
  1234.     if (nextc != -1 && keymap[nextc].type == ISFUNC)
  1235.       keymap[nextc].function = rl_quoted_insert;
  1236.       }
  1237. #ifdef IOCTL_DEBUG
  1238.     else
  1239.       {
  1240.         fprintf(stderr, "TIOCGLTC: %d\n", tty);
  1241.         perror("ioctl");
  1242.       }
  1243. #endif /*IOCTL_DEBUG*/
  1244.   }
  1245. #endif /* TIOCGLTC */
  1246. #else /* not NEW_TTY_DRIVER */
  1247.  
  1248. #if defined (_POSIX_VERSION)
  1249.   struct termios ttybuff;
  1250. #else
  1251.   struct termio ttybuff;
  1252. #endif /* POSIX */
  1253.   int tty = fileno (rl_instream);
  1254.  
  1255. #if defined (_POSIX_VERSION)
  1256.   if (tcgetattr (tty, &ttybuff) != -1)
  1257. #else
  1258.   if (ioctl (tty, TCGETA, &ttybuff) != -1)
  1259. #endif /* POSIX */
  1260.     {
  1261.       int erase = ttybuff.c_cc[VERASE];
  1262.       int ikill = ttybuff.c_cc[VKILL];
  1263.  
  1264.       if (erase != -1 && keymap[(unsigned char)erase].type == ISFUNC)
  1265.     keymap[(unsigned char)erase].function = rl_rubout;
  1266.  
  1267.       if (ikill != -1 && keymap[(unsigned char)ikill].type == ISFUNC)
  1268.     keymap[(unsigned char)ikill].function = rl_unix_line_discard;
  1269.     }
  1270. #endif /* NEW_TTY_DRIVER */
  1271. #ifdef IOCTL_DEBUG
  1272.   else
  1273.     {
  1274.       fprintf(stderr, "TCGETA: on %d\n", tty);
  1275.       perror("ioctl");
  1276.     }
  1277. #endif /*IOCTL_DEBUG*/
  1278. }
  1279.  
  1280.  
  1281. /* **************************************************************** */
  1282. /*                                    */
  1283. /*            Numeric Arguments                */
  1284. /*                                    */
  1285. /* **************************************************************** */
  1286.  
  1287. /* Handle C-u style numeric args, as well as M--, and M-digits. */
  1288.  
  1289. /* Add the current digit to the argument in progress. */
  1290. void rl_digit_argument (int ignore, int key)
  1291. {
  1292.   rl_pending_input = key;
  1293.   rl_digit_loop ();
  1294. }
  1295.  
  1296. /* What to do when you abort reading an argument. */
  1297. void rl_discard_argument (void)
  1298. {
  1299.   ding ();
  1300.   rl_clear_message ();
  1301.   rl_init_argument ();
  1302. }
  1303.  
  1304. /* Create a default argument. */
  1305. void rl_init_argument (void)
  1306. {
  1307.   rl_numeric_arg = arg_sign = 1;
  1308.   rl_explicit_arg = 0;
  1309. }
  1310.  
  1311. /* C-u, universal argument.  Multiply the current argument by 4.
  1312.    Read a key.  If the key has nothing to do with arguments, then
  1313.    dispatch on it.  If the key is the abort character then abort. */
  1314. void rl_universal_argument (int dum1, int dum2)
  1315. {
  1316.   rl_numeric_arg *= 4;
  1317.   rl_digit_loop ();
  1318. }
  1319.  
  1320. void rl_digit_loop (void)
  1321. {
  1322.   int key, c;
  1323.   while (1)
  1324.     {
  1325.       rl_message ("(arg: %d) ", arg_sign * rl_numeric_arg, 0);
  1326.       key = c = rl_read_key ();
  1327.  
  1328.       if (keymap[c].type == ISFUNC &&
  1329.       keymap[c].function == rl_universal_argument)
  1330.     {
  1331.       rl_numeric_arg *= 4;
  1332.       continue;
  1333.     }
  1334.       c = UNMETA (c);
  1335.       if (numeric (c))
  1336.     {
  1337.       if (rl_explicit_arg)
  1338.         rl_numeric_arg = (rl_numeric_arg * 10) + (c - '0');
  1339.       else
  1340.         rl_numeric_arg = (c - '0');
  1341.       rl_explicit_arg = 1;
  1342.     }
  1343.       else
  1344.     {
  1345.       if (c == '-' && !rl_explicit_arg)
  1346.         {
  1347.           rl_numeric_arg = 1;
  1348.           arg_sign = -1;
  1349.         }
  1350.       else
  1351.         {
  1352.           rl_clear_message ();
  1353.           rl_dispatch (key, keymap);
  1354.           return;
  1355.         }
  1356.     }
  1357.     }
  1358. }
  1359.  
  1360.  
  1361. /* **************************************************************** */
  1362. /*                                    */
  1363. /*            Display stuff                    */
  1364. /*                                    */
  1365. /* **************************************************************** */
  1366.  
  1367. /* This is the stuff that is hard for me.  I never seem to write good
  1368.    display routines in C.  Let's see how I do this time. */
  1369.  
  1370. /* (PWP) Well... Good for a simple line updater, but totally ignores
  1371.    the problems of input lines longer than the screen width.
  1372.  
  1373.    update_line and the code that calls it makes a multiple line,
  1374.    automatically wrapping line update.  Carefull attention needs
  1375.    to be paid to the vertical position variables.
  1376.  
  1377.    handling of terminals with autowrap on (incl. DEC braindamage)
  1378.    could be improved a bit.  Right now I just cheat and decrement
  1379.    screenwidth by one. */
  1380.  
  1381. /* Keep two buffers; one which reflects the current contents of the
  1382.    screen, and the other to draw what we think the new contents should
  1383.    be.  Then compare the buffers, and make whatever changes to the
  1384.    screen itself that we should.  Finally, make the buffer that we
  1385.    just drew into be the one which reflects the current contents of the
  1386.    screen, and place the cursor where it belongs.
  1387.  
  1388.    Commands that want to can fix the display themselves, and then let
  1389.    this function know that the display has been fixed by setting the
  1390.    RL_DISPLAY_FIXED variable.  This is good for efficiency. */
  1391.  
  1392. /* Termcap variables: */
  1393. extern char *term_up, *term_dc, *term_cr;
  1394. extern int screenheight, screenwidth, terminal_can_insert;
  1395.  
  1396. /* What YOU turn on when you have handled all redisplay yourself. */
  1397. int rl_display_fixed = 0;
  1398.  
  1399. /* The visible cursor position.  If you print some text, adjust this. */
  1400. int last_c_pos = 0;
  1401. int last_v_pos = 0;
  1402.  
  1403. /* The last left edge of text that was displayed.  This is used when
  1404.    doing horizontal scrolling.  It shifts in thirds of a screenwidth. */
  1405. static int last_lmargin = 0;
  1406.  
  1407. /* The line display buffers.  One is the line currently displayed on
  1408.    the screen.  The other is the line about to be displayed. */
  1409. static char *visible_line = (char *)NULL;
  1410. static char *invisible_line = (char *)NULL;
  1411.  
  1412. /* Number of lines currently on screen minus 1. */
  1413. int vis_botlin = 0;
  1414.  
  1415. /* A buffer for `modeline' messages. */
  1416. char msg_buf[128];
  1417.  
  1418. /* Non-zero forces the redisplay even if we thought it was unnecessary. */
  1419. int forced_display = 0;
  1420.  
  1421. /* The stuff that gets printed out before the actual text of the line.
  1422.    This is usually pointing to rl_prompt. */
  1423. char *rl_display_prompt = (char *)NULL;
  1424.  
  1425. /* Default and initial buffer size.  Can grow. */
  1426. static int line_size = 1024;
  1427.  
  1428. /* Non-zero means to always use horizontal scrolling in line display. */
  1429. static int horizontal_scroll_mode = 0;
  1430.  
  1431. /* Non-zero means to display an asterisk at the starts of history lines
  1432.    which have been modified. */
  1433. /* Who cares?
  1434. * static int mark_modified_lines = 0;
  1435. */
  1436.  
  1437. /* Non-zero means to use a visible bell if one is available rather than
  1438.    simply ringing the terminal bell. */
  1439. static int prefer_visible_bell = 0;
  1440.  
  1441. /* I really disagree with this, but my boss (among others) insists that we
  1442.    support compilers that don't work.  I don't think we are gaining by doing
  1443.    so; what is the advantage in producing better code if we can't use it? */
  1444. /* The following two declarations belong inside the
  1445.    function block, not here. */
  1446. static void move_cursor_relative (int , char *);
  1447. static void output_some_chars (char *, int );
  1448. static void output_character_function (int );
  1449. static int compare_strings (const void *, const void *);
  1450.  
  1451. /* Basic redisplay algorithm. */
  1452. void rl_redisplay (void)
  1453. {
  1454.   register int in, out, c, linenum;
  1455.   register char *line = invisible_line;
  1456.   char *prompt_this_line;
  1457.   int c_pos = 0;
  1458.   int inv_botlin = 0;        /* Number of lines in newly drawn buffer. */
  1459.  
  1460.   if (!readline_echoing_p)
  1461.     return;
  1462.  
  1463.   if (!rl_display_prompt)
  1464.     rl_display_prompt = "";
  1465.  
  1466.   if (!invisible_line)
  1467.     {
  1468.       visible_line = (char *)xmalloc (line_size);
  1469.       invisible_line = (char *)xmalloc (line_size);
  1470.       line = invisible_line;
  1471.       for (in = 0; in < line_size; in++)
  1472.     {
  1473.       visible_line[in] = 0;
  1474.       invisible_line[in] = 1;
  1475.     }
  1476.       rl_on_new_line ();
  1477.     }
  1478.  
  1479.   /* Draw the line into the buffer. */
  1480.   c_pos = -1;
  1481.  
  1482. /* Mark the line as modified or not.  We only do this for history lines. */
  1483. /* Is this really a feature ? *
  1484. * out = 0;
  1485. * if (mark_modified_lines && hl_current_history () && rl_undo_list)
  1486. *   {
  1487. *     line[out++] = '*';
  1488. *     line[out] = '\0';
  1489. *   }
  1490. **********/
  1491.  
  1492.   /* If someone thought that the redisplay was handled, but the currently
  1493.      visible line has a different modification state than the one about
  1494.      to become visible, then correct the callers misconception. */
  1495.   if (visible_line[0] != invisible_line[0])
  1496.       rl_display_fixed = 0;
  1497.  
  1498.   prompt_this_line = strrchr (rl_display_prompt, '\n');
  1499.   if (!prompt_this_line) {
  1500.       prompt_this_line = rl_display_prompt;
  1501.   }
  1502.   else {
  1503.       prompt_this_line++;
  1504.       if (forced_display)
  1505.           output_some_chars (rl_display_prompt,
  1506.                prompt_this_line - rl_display_prompt);
  1507.   }
  1508.  
  1509.   strncpy (line /* + out */,  prompt_this_line, strlen (prompt_this_line));
  1510.   out = strlen (prompt_this_line);
  1511.   line[out] = '\0';
  1512.  
  1513.   for (in = 0; in < rl_end; in++) {
  1514.       c = the_line[in];
  1515.  
  1516.       if (out + 1 >= line_size) {
  1517.         line_size *= 2;
  1518.         visible_line = (char *)xrealloc (visible_line, line_size);
  1519.         invisible_line = (char *)xrealloc (invisible_line, line_size);
  1520.         line = invisible_line;
  1521.       }
  1522.  
  1523.       if (in == rl_point)
  1524.         c_pos = out;
  1525.  
  1526.       if (c > 127) {
  1527.         line[out++] = 'M';
  1528.         line[out++] = '-';
  1529.         line[out++] = c - 128;
  1530.       }
  1531. #define DISPLAY_TABS
  1532. #ifdef DISPLAY_TABS
  1533.       else if (c == '\t') {
  1534.         register int newout = (out | (int)7) + 1;
  1535.         while (out < newout)
  1536.           line[out++] = ' ';
  1537.       }
  1538. #endif
  1539.       else if (c < 32) {
  1540.         line[out++] = 'C';
  1541.         line[out++] = '-';
  1542.         line[out++] = c + 64;
  1543.       }
  1544.       else {
  1545.         line[out++] = c;
  1546.       }
  1547.   }
  1548.   line[out] = '\0';
  1549.   if (c_pos < 0)
  1550.     c_pos = out;
  1551.  
  1552.   /* PWP: now is when things get a bit hairy.  The visible and invisible
  1553.      line buffers are really multiple lines, which would wrap every
  1554.      (screenwidth - 1) characters.  Go through each in turn, finding
  1555.      the changed region and updating it.  The line order is top to bottom. */
  1556.  
  1557.   /* If we can move the cursor up and down, then use multiple lines,
  1558.      otherwise, let long lines display in a single terminal line, and
  1559.      horizontally scroll it. */
  1560.  
  1561.   if (!horizontal_scroll_mode && term_up && *term_up) {
  1562.       int total_screen_chars = (screenwidth * screenheight);
  1563.  
  1564.       if (!rl_display_fixed || forced_display) {
  1565.           forced_display = 0;
  1566.  
  1567.       /* If we have more than a screenful of material to display, then
  1568.          only display a screenful.  We should display the last screen,
  1569.          not the first.  I'll fix this in a minute. */
  1570.           if (out >= total_screen_chars)
  1571.               out = total_screen_chars - 1;
  1572.  
  1573.       /* Number of screen lines to display. */
  1574.           inv_botlin = out / screenwidth;
  1575.  
  1576.       /* For each line in the buffer, do the updating display. */
  1577.           for (linenum = 0; linenum <= inv_botlin; linenum++) {
  1578.             update_line (linenum > vis_botlin ? ""
  1579.              : &visible_line[linenum * screenwidth],
  1580.              &invisible_line[linenum * screenwidth],
  1581.              linenum);
  1582.           }
  1583.  
  1584.       /* We may have deleted some lines.  If so, clear the left over
  1585.          blank ones at the bottom out. */
  1586.           if (vis_botlin > inv_botlin) {
  1587.               char *tt;
  1588.               for (; linenum <= vis_botlin; linenum++) {
  1589.                   tt = &visible_line[linenum * screenwidth];
  1590.                   move_vert (linenum);
  1591.                   move_cursor_relative (0, tt);
  1592.                   clear_to_eol ((linenum == vis_botlin)?
  1593.                         strlen (tt) : screenwidth);
  1594.               }
  1595.           }
  1596.           vis_botlin = inv_botlin;
  1597.  
  1598.       /* Move the cursor where it should be. */
  1599.           move_vert (c_pos / screenwidth);
  1600.           move_cursor_relative (c_pos % screenwidth,
  1601.                 &invisible_line[(c_pos / screenwidth) * screenwidth]);
  1602.       }
  1603.   }
  1604.   else {                /* Do horizontal scrolling. */
  1605.       int lmargin;
  1606.  
  1607.       /* Always at top line. */
  1608.       last_v_pos = 0;
  1609.  
  1610.       /* If the display position of the cursor would be off the edge
  1611.      of the screen, start the display of this line at an offset that
  1612.      leaves the cursor on the screen. */
  1613.       if (c_pos - last_lmargin > screenwidth - 2)
  1614.           lmargin = (c_pos / (screenwidth / 3) - 2) * (screenwidth / 3);
  1615.       else if (c_pos - last_lmargin < 1)
  1616.           lmargin = ((c_pos - 1) / (screenwidth / 3)) * (screenwidth / 3);
  1617.       else
  1618.           lmargin = last_lmargin;
  1619.  
  1620.       /* If the first character on the screen isn't the first character
  1621.      in the display line, indicate this with a special character. */
  1622.       if (lmargin > 0)
  1623.           line[lmargin] = '<';
  1624.  
  1625.       if (lmargin + screenwidth < out)
  1626.           line[lmargin + screenwidth - 1] = '>';
  1627.  
  1628.       if (!rl_display_fixed || forced_display || lmargin != last_lmargin) {
  1629.           forced_display = 0;
  1630.           update_line (&visible_line[last_lmargin],
  1631.                    &invisible_line[lmargin], 0);
  1632.  
  1633.           move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
  1634.           last_lmargin = lmargin;
  1635.       }
  1636.   }
  1637.   fflush (out_stream);
  1638.  
  1639.   /* Swap visible and non-visible lines. */
  1640.   {
  1641.     char *temp = visible_line;
  1642.     visible_line = invisible_line;
  1643.     invisible_line = temp;
  1644.     rl_display_fixed = 0;
  1645.   }
  1646. }
  1647.  
  1648. /* PWP: update_line() is based on finding the middle difference of each
  1649.    line on the screen; vis:
  1650.  
  1651.                  /old first difference
  1652.     /beginning of line   |              /old last same       /old EOL
  1653.     v             v              v                    v
  1654. old:    eddie> Oh, my little gruntle-buggy is to me, as lurgid as
  1655. new:    eddie> Oh, my little buggy says to me, as lurgid as
  1656.     ^             ^        ^               ^
  1657.     \beginning of line   |        \new last same       \new end of line
  1658.                  \new first difference
  1659.  
  1660.    All are character pointers for the sake of speed.  Special cases for
  1661.    no differences, as well as for end of line additions must be handeled.
  1662.  
  1663.    Could be made even smarter, but this works well enough */
  1664. static
  1665. void update_line (register char *old, register char *new, int current_line)
  1666. {
  1667.   register char *ofd, *ols, *oe, *nfd, *nls, *ne;
  1668.   int lendiff, wsatend;
  1669.  
  1670.   /* Find first difference. */
  1671.   for (ofd = old, nfd = new;
  1672.        (ofd - old < screenwidth) && *ofd && (*ofd == *nfd);
  1673.        ofd++, nfd++)
  1674.     ;
  1675.  
  1676.   /* Move to the end of the screen line. */
  1677.   for (oe = ofd; ((oe - old) < screenwidth) && *oe; oe++) 
  1678.     ;
  1679.   for (ne = nfd; ((ne - new) < screenwidth) && *ne; ne++) 
  1680.     ;
  1681.  
  1682.   /* If no difference, continue to next line. */
  1683.   if (ofd == oe && nfd == ne)
  1684.     return;
  1685.  
  1686.   wsatend = 1;            /* flag for trailing whitespace */
  1687.   ols = oe - 1;            /* find last same */
  1688.   nls = ne - 1;
  1689.   while ((*ols == *nls) && (ols > ofd) && (nls > nfd))
  1690.     {
  1691.       if (*ols != ' ')
  1692.     wsatend = 0;
  1693.       ols--;
  1694.       nls--;
  1695.     }
  1696.  
  1697.   if (wsatend)
  1698.     {
  1699.       ols = oe;
  1700.       nls = ne;
  1701.     }
  1702.   else if (*ols != *nls)
  1703.     {
  1704.       if (*ols)            /* don't step past the NUL */
  1705.     ols++;
  1706.       if (*nls)
  1707.     nls++;
  1708.     }
  1709.  
  1710.   move_vert (current_line);
  1711.   move_cursor_relative (ofd - old, old);
  1712.  
  1713.   /* if (len (new) > len (old)) */
  1714.   lendiff = (nls - nfd) - (ols - ofd);
  1715.  
  1716.   /* Insert (diff(len(old),len(new)) ch */
  1717.   if (lendiff > 0)
  1718.     {
  1719.       if (terminal_can_insert)
  1720.     {
  1721.       extern char *term_IC;
  1722.  
  1723.       /* Sometimes it is cheaper to print the characters rather than
  1724.          use the terminal's capabilities. */
  1725.       if ((2 * (ne - nfd)) < lendiff && !term_IC)
  1726.         {
  1727.           output_some_chars (nfd, (ne - nfd));
  1728.           last_c_pos += (ne - nfd);
  1729.         }
  1730.       else
  1731.         {
  1732.           if (*ols)
  1733.         {
  1734.           insert_some_chars (nfd, lendiff);
  1735.           last_c_pos += lendiff;
  1736.         }
  1737.           else
  1738.         {
  1739.           /* At the end of a line the characters do not have to
  1740.              be "inserted".  They can just be placed on the screen. */
  1741.           output_some_chars (nfd, lendiff);
  1742.           last_c_pos += lendiff;
  1743.         }
  1744.           /* Copy (new) chars to screen from first diff to last match. */
  1745.           if (((nls - nfd) - lendiff) > 0)
  1746.         {
  1747.           output_some_chars (&nfd[lendiff], ((nls - nfd) - lendiff));
  1748.           last_c_pos += ((nls - nfd) - lendiff);
  1749.         }
  1750.         }
  1751.     }
  1752.       else
  1753.     {        /* cannot insert chars, write to EOL */
  1754.       output_some_chars (nfd, (ne - nfd));
  1755.       last_c_pos += (ne - nfd);
  1756.     }
  1757.     }
  1758.   else                /* Delete characters from line. */
  1759.     {
  1760.       /* If possible and inexpensive to use terminal deletion, then do so. */
  1761.       if (term_dc && (2 * (ne - nfd)) >= (-lendiff))
  1762.     {
  1763.       if (lendiff)
  1764.         delete_chars (-lendiff); /* delete (diff) characters */
  1765.  
  1766.       /* Copy (new) chars to screen from first diff to last match */
  1767.       if ((nls - nfd) > 0)
  1768.         {
  1769.           output_some_chars (nfd, (nls - nfd));
  1770.           last_c_pos += (nls - nfd);
  1771.         }
  1772.     }
  1773.       /* Otherwise, print over the existing material. */
  1774.       else
  1775.     {
  1776.       output_some_chars (nfd, (ne - nfd));
  1777.       last_c_pos += (ne - nfd);
  1778.       clear_to_eol ((oe - old) - (ne - new));
  1779.     }
  1780.     }
  1781. }
  1782.  
  1783. /* (PWP) tell the update routines that we have moved onto a
  1784.    new (empty) line. */
  1785. void rl_on_new_line (void)
  1786. {
  1787.   if (visible_line)
  1788.     visible_line[0] = '\0';
  1789.  
  1790.   last_c_pos = last_v_pos = 0;
  1791.   vis_botlin = last_lmargin = 0;
  1792. }
  1793.  
  1794. /* Actually update the display, period. */
  1795. void rl_forced_update_display (void)
  1796. {
  1797.   if (visible_line)
  1798.     {
  1799.       register char *temp = visible_line;
  1800.  
  1801.       while (*temp) *temp++ = '\0';
  1802.     }
  1803.   rl_on_new_line ();
  1804.   forced_display++;
  1805.   rl_redisplay ();
  1806. }
  1807.  
  1808. /* Move the cursor from last_c_pos to NEW, which are buffer indices.
  1809.    DATA is the contents of the screen line of interest; i.e., where
  1810.    the movement is being done. */
  1811. static void
  1812. move_cursor_relative (int new, char *data)
  1813. {
  1814.   register int i;
  1815.  
  1816.   /* It may be faster to output a CR, and then move forwards instead
  1817.      of moving backwards. */
  1818.   if (new + 1 < last_c_pos - new)
  1819.     {
  1820.       tputs (term_cr, 1, output_character_function);
  1821.       last_c_pos = 0;
  1822.     }
  1823.  
  1824.   if (last_c_pos == new) return;
  1825.  
  1826.   if (last_c_pos < new)
  1827.     {
  1828.       /* Move the cursor forward.  We do it by printing the command
  1829.      to move the cursor forward if there is one, else print that
  1830.      portion of the output buffer again.  Which is cheaper? */
  1831.  
  1832.       /* The above comment is left here for posterity.  It is faster
  1833.      to print one character (non-control) than to print a control
  1834.      sequence telling the terminal to move forward one character.
  1835.      That kind of control is for people who don't know what the
  1836.      data is underneath the cursor. */
  1837. #ifdef HACK_TERMCAP_MOTION
  1838.       extern char *term_forward_char;
  1839.  
  1840.       if (term_forward_char)
  1841.     for (i = last_c_pos; i < new; i++)
  1842.       tputs (term_forward_char, 1, output_character_function);
  1843.       else
  1844.     for (i = last_c_pos; i < new; i++)
  1845.       putc (data[i], out_stream);
  1846. #else
  1847.       for (i = last_c_pos; i < new; i++)
  1848.     putc (data[i], out_stream);
  1849. #endif                /* HACK_TERMCAP_MOTION */
  1850.     }
  1851.   else
  1852.     backspace (last_c_pos - new);
  1853.   last_c_pos = new;
  1854. }
  1855.  
  1856. /* PWP: move the cursor up or down. */
  1857. void move_vert (int to)
  1858. {
  1859.   register int delta, i;
  1860.  
  1861.   if (last_v_pos == to) return;
  1862.  
  1863.   if (to > screenheight)
  1864.     return;
  1865.  
  1866.   if ((delta = to - last_v_pos) > 0)
  1867.     {
  1868.       for (i = 0; i < delta; i++)
  1869.     putc ('\n', out_stream);
  1870.       tputs (term_cr, 1, output_character_function);
  1871.       last_c_pos = 0;        /* because crlf() will do \r\n */
  1872.     }
  1873.   else
  1874.     {            /* delta < 0 */
  1875.       if (term_up && *term_up)
  1876.     for (i = 0; i < -delta; i++)
  1877.       tputs (term_up, 1, output_character_function);
  1878.     }
  1879.   last_v_pos = to;        /* now to is here */
  1880. }
  1881.  
  1882. /* Physically print C on out_stream.  This is for functions which know
  1883.    how to optimize the display. */
  1884. void rl_show_char (int c)
  1885. {
  1886.   if (c > 127)
  1887.     {
  1888.       fprintf (out_stream, "M-");
  1889.       c -= 128;
  1890.     }
  1891.  
  1892. #ifdef DISPLAY_TABS
  1893.   if (c < 32 && c != '\t')
  1894. #else
  1895.   if (c < 32)
  1896. #endif
  1897.     {
  1898.  
  1899.       c += 64;
  1900.     }
  1901.  
  1902.   putc (c, out_stream);
  1903.   fflush (out_stream);
  1904. }
  1905.  
  1906. #ifdef DISPLAY_TABS
  1907. int
  1908. rl_character_len (register int c, register int pos)
  1909. {
  1910.   if (c < ' ' || c > 126)
  1911.     {
  1912.       if (c == '\t')
  1913.     return (((pos | (int)7) + 1) - pos);
  1914.       else
  1915.     return (3);
  1916.     }
  1917.   else
  1918.     return (1);
  1919. }
  1920. #else
  1921. int
  1922. rl_character_len (c)
  1923.      int c;
  1924. {
  1925.   if (c < ' ' || c > 126)
  1926.     return (3);
  1927.   else
  1928.     return (1);
  1929. }
  1930. #endif  /* DISPLAY_TAB */
  1931.  
  1932. /* How to print things in the "echo-area".  The prompt is treated as a
  1933.    mini-modeline. */
  1934. void rl_message (char *string, int arg1, int arg2)
  1935. {
  1936.   sprintf (msg_buf, string, arg1, arg2);
  1937.   rl_display_prompt = msg_buf;
  1938.   rl_redisplay ();
  1939. }
  1940.  
  1941. /* How to clear things from the "echo-area". */
  1942. void rl_clear_message (void)
  1943. {
  1944.   rl_display_prompt = rl_prompt;
  1945.   rl_redisplay ();
  1946. }
  1947.  
  1948. /* **************************************************************** */
  1949. /*                                    */
  1950. /*            Terminal and Termcap                */
  1951. /*                                    */
  1952. /* **************************************************************** */
  1953.  
  1954. static char *term_buffer = (char *)NULL;
  1955. static char *term_string_buffer = (char *)NULL;
  1956.  
  1957. /* Some strings to control terminal actions.  These are output by tputs (). */
  1958. char *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace;
  1959.  
  1960. int screenwidth, screenheight;
  1961.  
  1962. /* Non-zero if we determine that the terminal can do character insertion. */
  1963. int terminal_can_insert = 0;
  1964.  
  1965. /* How to insert characters. */
  1966. char *term_im, *term_ei, *term_ic, *term_ip, *term_IC;
  1967.  
  1968. /* How to delete characters. */
  1969. char *term_dc, *term_DC;
  1970.  
  1971. #ifdef HACK_TERMCAP_MOTION
  1972. char *term_forward_char;
  1973. #endif  /* HACK_TERMCAP_MOTION */
  1974.  
  1975. /* How to go up a line. */
  1976. char *term_up;
  1977.  
  1978. /* A visible bell, if the terminal can be made to flash the screen. */
  1979. char *visible_bell;
  1980.  
  1981. /* Re-initialize the terminal considering that the TERM/TERMCAP variable
  1982.    has changed. */
  1983. void rl_reset_terminal (char *terminal_name)
  1984. {
  1985.   init_terminal_io (terminal_name);
  1986. }
  1987.  
  1988. void init_terminal_io (char *terminal_name)
  1989. {
  1990.   char *term = (terminal_name? terminal_name : (char *)getenv ("TERM"));
  1991.   char *tgetstr (char *, char **), *buffer;
  1992. #ifdef TIOCGWINSZ
  1993.   struct winsize window_size;
  1994. #endif
  1995.   int tty;
  1996.  
  1997.   if (!term_string_buffer)
  1998.     term_string_buffer = (char *)xmalloc (2048);
  1999.  
  2000.   if (!term_buffer)
  2001.     term_buffer = (char *)xmalloc (2048);
  2002.  
  2003.   buffer = term_string_buffer;
  2004.  
  2005.   term_clrpag = term_cr = term_clreol = (char *)NULL;
  2006.  
  2007.   if (!term) {
  2008.     term = "dumb";
  2009.     fprintf(stderr, "Warning: TERM not defined: Using dumb terminal.\n");
  2010.   }
  2011.  
  2012.   while (tgetent (term_buffer, term) < 0) {
  2013.       if (strcmp(term, "dumb") == 0) {
  2014.           fprintf(stderr,
  2015.           "Warning: Cannot find dumb terminal entry. Please verify termcap!\n");
  2016.           return;
  2017.       }
  2018.       fprintf(stderr,
  2019.       "Warning: Unknown terminal `%s': Using dumb terminal.\n", term);
  2020.       term = "dumb";
  2021.   }
  2022.  
  2023.   term_backspace = tgetstr ("le", &buffer);
  2024.   term_cr = tgetstr ("cr", &buffer);
  2025.   term_clreol = tgetstr ("ce", &buffer);
  2026.   term_clrpag = tgetstr ("cl", &buffer);
  2027.  
  2028.   if (!term_cr)
  2029.     term_cr =  "\r";
  2030.  
  2031. #ifdef HACK_TERMCAP_MOTION
  2032.   term_forward_char = tgetstr ("nd", &buffer);
  2033. #endif  /* HACK_TERMCAP_MOTION */
  2034.  
  2035.   if (rl_instream)
  2036.     tty = fileno (rl_instream);
  2037.   else
  2038.     tty = 0;
  2039.     
  2040.   screenwidth = screenheight = 0;
  2041. #ifdef TIOCGWINSZ
  2042.   if (ioctl (tty, TIOCGWINSZ, &window_size) == 0) {
  2043.       screenwidth = (int) window_size.ws_col;
  2044.       screenheight = (int) window_size.ws_row;
  2045.   }
  2046. #endif
  2047.  
  2048.   if (screenwidth <= 0 || screenheight <= 0) {
  2049.       screenwidth = tgetnum ("co");
  2050.       screenheight = tgetnum ("li");
  2051.   }
  2052.  
  2053.   screenwidth--;
  2054.  
  2055.   if (screenwidth <= 0)
  2056.     screenwidth = 79;
  2057.  
  2058.   if (screenheight <= 0)
  2059.     screenheight = 24;
  2060.  
  2061.   term_im = tgetstr ("im", &buffer);
  2062.   term_ei = tgetstr ("ei", &buffer);
  2063.   term_IC = tgetstr ("IC", &buffer);
  2064.   term_ic = tgetstr ("ic", &buffer);
  2065.  
  2066.   /* "An application program can assume that the terminal can do
  2067.       character insertion if *any one of* the capabilities `IC',
  2068.       `im', `ic' or `ip' is provided."  But we can't do anything if
  2069.       only `ip' is provided, so... */
  2070.   terminal_can_insert = (term_IC || term_im || term_ic);
  2071.  
  2072.   term_up = tgetstr ("up", &buffer);
  2073.   term_dc = tgetstr ("dc", &buffer);
  2074.   term_DC = tgetstr ("DC", &buffer);
  2075.  
  2076.   visible_bell = tgetstr ("vb", &buffer);
  2077. }
  2078.  
  2079. /* A function for the use of tputs () */
  2080. static void
  2081. output_character_function (int c)
  2082. {
  2083.   putc (c, out_stream);
  2084. }
  2085.  
  2086. /* Write COUNT characters from STRING to the output stream. */
  2087. static void
  2088. output_some_chars (char *string, int count)
  2089. {
  2090.   fwrite (string, 1, count, out_stream);
  2091. }
  2092.  
  2093. /* Delete COUNT characters from the display line. */
  2094. static void
  2095. delete_chars (int count)
  2096. {
  2097.   if (count > screenwidth)
  2098.     return;
  2099.  
  2100.   if (term_DC && *term_DC)
  2101.     {
  2102.       char *tgoto (char *, int, int), *buffer;
  2103.       buffer = tgoto (term_DC, 0, count);
  2104.       tputs (buffer, 1, output_character_function);
  2105.     }
  2106.   else
  2107.     {
  2108.       if (term_dc && *term_dc)
  2109.     while (count--)
  2110.       tputs (term_dc, 1, output_character_function);
  2111.     }
  2112. }
  2113.  
  2114. /* Insert COUNT characters from STRING to the output stream. */
  2115. static void
  2116. insert_some_chars (char *string, int count)
  2117. {
  2118.   /* If IC is defined, then we do not have to "enter" insert mode. */
  2119.   if (term_IC)
  2120.     {
  2121.       char *tgoto (char *, int, int), *buffer;
  2122.       buffer = tgoto (term_IC, 0, count);
  2123.       tputs (buffer, 1, output_character_function);
  2124.       output_some_chars (string, count);
  2125.     }
  2126.   else
  2127.     {
  2128.       register int i;
  2129.  
  2130.       /* If we have to turn on insert-mode, then do so. */
  2131.       if (term_im && *term_im)
  2132.     tputs (term_im, 1, output_character_function);
  2133.  
  2134.       /* If there is a special command for inserting characters, then
  2135.      use that first to open up the space. */
  2136.       if (term_ic && *term_ic)
  2137.     {
  2138.       for (i = count; i--; )
  2139.         tputs (term_ic, 1, output_character_function);
  2140.     }
  2141.  
  2142.       /* Print the text. */
  2143.       output_some_chars (string, count);
  2144.  
  2145.       /* If there is a string to turn off insert mode, we had best use
  2146.      it now. */
  2147.       if (term_ei && *term_ei)
  2148.     tputs (term_ei, 1, output_character_function);
  2149.     }
  2150. }
  2151.  
  2152. /* Move the cursor back. */
  2153. void backspace (int count)
  2154. {
  2155.   register int i;
  2156.  
  2157.   if (term_backspace)
  2158.     for (i = 0; i < count; i++)
  2159.       tputs (term_backspace, 1, output_character_function);
  2160.   else
  2161.     for (i = 0; i < count; i++)
  2162.       putc ('\b', out_stream);
  2163. }
  2164.  
  2165. /* Move to the start of the next line. */
  2166. void crlf (void)
  2167. {
  2168.   tputs (term_cr, 1, output_character_function);
  2169.   putc ('\n', out_stream);
  2170. }
  2171.  
  2172. /* Clear to the end of the line.  COUNT is the minimum
  2173.    number of character spaces to clear, */
  2174. void clear_to_eol (int count)
  2175. {
  2176.   if (term_clreol)
  2177.     {
  2178.       tputs (term_clreol, 1, output_character_function);
  2179.     }
  2180.   else
  2181.     {
  2182.       register int i;
  2183.  
  2184.       /* Do one more character space. */
  2185.       count++;
  2186.  
  2187.       for (i = 0; i < count; i++)
  2188.     putc (' ', out_stream);
  2189.  
  2190.       backspace (count);
  2191.     }
  2192. }
  2193.  
  2194. /* **************************************************************** */
  2195. /*                                    */
  2196. /*              Saving and Restoring the TTY                */
  2197. /*                                    */
  2198. /* **************************************************************** */
  2199.  
  2200. /* Non-zero means that the terminal is in a prepped state. */
  2201. static int terminal_prepped = 0;
  2202.  
  2203. #ifdef NEW_TTY_DRIVER
  2204.  
  2205. /* Standard flags, including ECHO. */
  2206. static int original_tty_flags = 0;
  2207.  
  2208. /* Local mode flags, like LPASS8. */
  2209. static int local_mode_flags = 0;
  2210.  
  2211. /* Terminal characters.  This has C-s and C-q in it. */
  2212. static struct tchars original_tchars;
  2213.  
  2214. /* Local special characters.  This has the interrupt characters in it. */
  2215. static struct ltchars original_ltchars;
  2216.  
  2217. /* We use this to get and set the tty_flags. */
  2218. static struct sgttyb the_ttybuff;
  2219.  
  2220. /* Put the terminal in CBREAK mode so that we can detect key presses. */
  2221. static void
  2222. rl_prep_terminal ()
  2223. {
  2224.   int tty = fileno (rl_instream);
  2225.   int oldmask = sigblock (sigmask (SIGINT));
  2226.  
  2227.   if (!terminal_prepped)
  2228.     {
  2229.       /* We always get the latest tty values.  Maybe stty changed them. */
  2230.       if (ioctl (tty, TIOCGETP, &the_ttybuff) < 0) {
  2231. #ifdef IOCTL_DEBUG
  2232.         fprintf(stderr, "TIOCGETP: on %d\n", tty);
  2233.         perror("ioctl");
  2234. #endif /*IOCTL_DEBUG*/
  2235.       }
  2236.     }
  2237.       original_tty_flags = the_ttybuff.sg_flags;
  2238.  
  2239.       readline_echoing_p = (original_tty_flags & ECHO);
  2240.  
  2241. #if defined (TIOCLGET)
  2242.       if (ioctl (tty, TIOCLGET, &local_mode_flags) < 0) {
  2243. #ifdef IOCTL_DEBUG
  2244.         fprintf(stderr, "TIOCLGET: on %d\n", tty);
  2245.         perror("ioctl");
  2246. #endif /*IOCTL_DEBUG*/
  2247.       }
  2248. #endif
  2249.  
  2250. #if !defined (ANYP)
  2251. #define ANYP (EVENP | ODDP)
  2252. #endif
  2253.       /* If this terminal doesn't care how the 8th bit is used,
  2254.      then we can use it for the meta-key.
  2255.      We check by seeing if BOTH odd and even parity are allowed. */
  2256.       if (the_ttybuff.sg_flags & ANYP)
  2257.     {
  2258. #if defined (PASS8)
  2259.       the_ttybuff.sg_flags |= PASS8;
  2260. #endif
  2261.  
  2262.       /* Hack on local mode flags if we can. */
  2263. #if defined (TIOCLGET) && defined (LPASS8)
  2264.       {
  2265.         int flags;
  2266.         flags = local_mode_flags | LPASS8;
  2267.         if (ioctl (tty, TIOCLSET, &flags) < 0) {
  2268. #ifdef IOCTL_DEBUG
  2269.             fprintf(stderr, "TIOCLSET: on %d\n", tty);
  2270.             perror("ioctl");
  2271. #endif /*IOCTL_DEBUG*/
  2272.         }
  2273.       }
  2274. #endif /* TIOCLGET && LPASS8 */
  2275.     }
  2276. #ifdef TIOCGETC
  2277.       {
  2278.     struct tchars temp;
  2279.  
  2280.     if (ioctl (tty, TIOCGETC, &original_tchars) < 0) {
  2281. #ifdef IOCTL_DEBUG
  2282.         fprintf(stderr, "TIOCGETC: on %d\n", tty);
  2283.         perror("ioctl");
  2284. #endif /*IOCTL_DEBUG*/
  2285.     }
  2286.     temp = original_tchars;
  2287.  
  2288.     /* Get rid of C-s and C-q.
  2289.        We remember the value of startc (C-q) so that if the terminal is in
  2290.        xoff state, the user can xon it by pressing that character. */
  2291.     xon_char = temp.t_startc;
  2292.     temp.t_stopc = -1;
  2293.     temp.t_startc = -1;
  2294.  
  2295.     /* If there is an XON character, bind it to restart the output. */
  2296.     if (xon_char != -1)
  2297.       rl_bind_key (xon_char, rl_restart_output);
  2298.  
  2299.     /* If there is an EOF char, bind eof_char to it. */
  2300.     if (temp.t_eofc != -1)
  2301.       eof_char = temp.t_eofc;
  2302.  
  2303. #if defined (NOTDEF)
  2304.     /* Get rid of C-\ and C-c. */
  2305.     temp.t_intrc = temp.t_quitc = -1;
  2306. #endif /* NOTDEF */
  2307.  
  2308.     if (ioctl (tty, TIOCSETC, &temp) < 0) {
  2309. #ifdef IOCTL_DEBUG
  2310.         fprintf(stderr, "TIOCSETC: on %d\n", tty);
  2311.         perror("ioctl");
  2312. #endif /*IOCTL_DEBUG*/
  2313.     }
  2314. #endif /* TIOCGETC */
  2315.  
  2316. #ifdef TIOCGLTC
  2317.       {
  2318.     struct ltchars temp;
  2319.  
  2320.     if (ioctl (tty, TIOCGLTC, &original_ltchars) < 0) {
  2321. #ifdef IOCTL_DEBUG
  2322.         fprintf(stderr, "TIOCGLTC: on %d\n", tty);
  2323.         perror("ioctl");
  2324. #endif /*IOCTL_DEBUG*/
  2325.     }
  2326.     temp = original_ltchars;
  2327.  
  2328.     /* Make the interrupt keys go away.  Just enough to make people
  2329.        happy. */
  2330.     temp.t_dsuspc = -1;    /* C-y */
  2331.     temp.t_lnextc = -1;    /* C-v */
  2332.  
  2333.     if (ioctl (tty, TIOCSLTC, &temp) < 0) {
  2334. #ifdef IOCTL_DEBUG
  2335.         fprintf(stderr, "TIOCSLTC: on %d\n", tty);
  2336.         perror("ioctl");
  2337. #endif /*IOCTL_DEBUG*/
  2338.     }
  2339.       }
  2340. #endif /* TIOCGLTC */
  2341.  
  2342.       the_ttybuff.sg_flags &= (~ECHO|CRMOD);
  2343.       /* fprintf(stderr, "Setting cbreak.\n"); */
  2344.       the_ttybuff.sg_flags |= CBREAK;
  2345.       if  (ioctl (tty, TIOCSETN, &the_ttybuff) <0) {
  2346. #ifdef IOCTL_DEBUG
  2347.         fprintf(stderr, "TIOCSETN: on %d\n", tty);
  2348.         perror("ioctl");
  2349. #endif /*IOCTL_DEBUG*/
  2350.       }
  2351.       terminal_prepped = 1;
  2352.     }
  2353.   sigsetmask (oldmask);
  2354. }
  2355.  
  2356. /* Restore the terminal to its original state. */
  2357. static void
  2358. rl_deprep_terminal ()
  2359. {
  2360.   int tty = fileno (rl_instream);
  2361.   int oldmask = sigblock (sigmask (SIGINT));
  2362.  
  2363.   if (terminal_prepped)
  2364.     {
  2365.       the_ttybuff.sg_flags = original_tty_flags;
  2366.       ioctl (tty, TIOCSETN, &the_ttybuff);
  2367.       readline_echoing_p = 1;
  2368.  
  2369. #if defined (TIOCLGET)
  2370.       ioctl (tty, TIOCLSET, &local_mode_flags);
  2371. #endif
  2372.  
  2373. #ifdef TIOCSLTC
  2374.       ioctl (tty, TIOCSLTC, &original_ltchars);
  2375. #endif
  2376.  
  2377. #ifdef TIOCSETC
  2378.       ioctl (tty, TIOCSETC, &original_tchars);
  2379. #endif
  2380.       terminal_prepped = 0;
  2381.     }
  2382.   sigsetmask (oldmask);
  2383. }
  2384.  
  2385. #else  /* !defined (NEW_TTY_DRIVER) */
  2386.  
  2387. #if !defined (VMIN)
  2388. #define VMIN VEOF
  2389. #endif
  2390.  
  2391. #if !defined (VTIME)
  2392. #define VTIME VEOL
  2393. #endif
  2394.  
  2395. #if defined (_POSIX_VERSION)
  2396. static struct termios otio;
  2397. #else
  2398. static struct termio otio;
  2399. #endif
  2400.  
  2401. static void
  2402. rl_prep_terminal (void)
  2403. {
  2404.   int tty = fileno (rl_instream);
  2405. #if defined (_POSIX_VERSION)
  2406.   struct termios tio;
  2407. #else
  2408.   struct termio tio;
  2409. #endif
  2410.  
  2411.   /* If we are on a Posix system, block the delivery of SIGINT for a while. */
  2412. #if defined (_POSIX_VERSION)
  2413.   sigset_t set, oset;
  2414.  
  2415.   sigemptyset (&set);
  2416.   sigaddset (&set, SIGINT);
  2417.   sigprocmask (SIG_BLOCK, &set, &oset);
  2418. #else 
  2419. #  if defined (HAVE_BSD_SIGNALS)
  2420.   int oldmask = sigblock (sigmask (SIGINT));
  2421. #  endif /* HAVE_BSD_SIGNALS */
  2422. #endif /* POSIX */
  2423.  
  2424. #if defined (_POSIX_VERSION)
  2425.   tcgetattr (tty, &tio);
  2426. #else
  2427.   ioctl (tty, TCGETA, &tio);
  2428. #endif /* POSIX */
  2429.  
  2430.   otio = tio;
  2431.  
  2432.   readline_echoing_p = (tio.c_lflag & ECHO);
  2433.  
  2434.   tio.c_lflag &= ~(ICANON|ECHO);
  2435.  
  2436. #if defined (IXANY)
  2437.   tio.c_iflag &= ~(IXON|IXOFF|IXANY);
  2438. #else
  2439.   /* `strict' Posix systems do not define IXANY. */
  2440.   tio.c_iflag &= ~(IXON|IXOFF);
  2441. #endif /* IXANY */
  2442.  
  2443.   /* Only turn this off if we are using all 8 bits. */
  2444.   /* |ISTRIP|INPCK */
  2445.  
  2446. #if !defined (HANDLE_SIGNALS)
  2447.   tio.c_lflag &= ~ISIG;
  2448. #else
  2449.   tio.c_lflag |= ISIG;    /* shouldn't be needed, but... */
  2450. #endif
  2451.  
  2452.   tio.c_cc[VMIN] = 1;
  2453.   tio.c_cc[VTIME] = 0;
  2454.  
  2455.   /* Turn off characters that we need on Posix systems with job control,
  2456.      just to be sure.  This includes ^Y and ^V.  This should not really
  2457.      be necessary.  */
  2458. #if defined (_POSIX_VERSION) && defined (_POSIX_JOB_CONTROL)
  2459.  
  2460. #if !defined (_POSIX_VDISABLE)
  2461. #define _POSIX_VDISABLE    0
  2462. #endif /* POSIX_VDISABLE */
  2463.  
  2464. #if defined (VLNEXT)
  2465.   tio.c_cc[VLNEXT] = _POSIX_VDISABLE;
  2466. #endif
  2467.  
  2468. #if defined (VDSUSP)
  2469.   tio.c_cc[VDSUSP] = _POSIX_VDISABLE;
  2470. #endif
  2471.  
  2472. #endif /* POSIX && JOB_CONTROL */
  2473.  
  2474. #if defined (_POSIX_VERSION)
  2475.   tcsetattr (tty, TCSADRAIN, &tio);
  2476. #ifndef AMIGA
  2477.   tcflow (tty, TCOON);        /* Simulate a ^Q. */
  2478. #endif
  2479. #else
  2480.   ioctl (tty, TCSETAW, &tio);
  2481.   ioctl (tty, TCXONC, 1);    /* Simulate a ^Q. */
  2482. #endif /* POSIX */
  2483.  
  2484. #if defined (_POSIX_VERSION)
  2485.   sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
  2486. #else
  2487. #  if defined (HAVE_BSD_SIGNALS)
  2488.   sigsetmask (oldmask);
  2489. #  endif /* HAVE_BSD_SIGNALS */
  2490. #endif /* POSIX */
  2491. }
  2492.  
  2493. static void
  2494. rl_deprep_terminal (void)
  2495. {
  2496.   int tty = fileno (rl_instream);
  2497.  
  2498.   /* If we are on a Posix system, block the delivery of SIGINT for a while. */
  2499. #if defined (_POSIX_VERSION)
  2500.   sigset_t set, oset;
  2501.  
  2502.   sigemptyset (&set);
  2503.   sigaddset (&set, SIGINT);
  2504.   sigprocmask (SIG_BLOCK, &set, &oset);
  2505. #else
  2506. #  if defined (HAVE_BSD_SIGNALS)
  2507.   int oldmask = sigblock (sigmask (SIGINT));
  2508. #  endif /* HAVE_BSD_SIGNALS */
  2509. #endif /* POSIX */
  2510.  
  2511. #if defined (_POSIX_VERSION)
  2512.   tcsetattr (tty, TCSADRAIN, &otio);
  2513. #ifndef AMIGA
  2514.   tcflow (tty, TCOON);        /* Simulate a ^Q. */
  2515. #endif
  2516. #else
  2517.   ioctl (tty, TCSETAW, &otio);
  2518.   ioctl (tty, TCXONC, 1);    /* Simulate a ^Q. */
  2519. #endif /* POSIX */
  2520.  
  2521. #if defined (_POSIX_VERSION)
  2522.   sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
  2523. #else
  2524. #  if defined (HAVE_BSD_SIGNALS)
  2525.   sigsetmask (oldmask);
  2526. #  endif /* HAVE_BSD_SIGNALS */
  2527. #endif /* POSIX */
  2528. }
  2529. #endif  /* NEW_TTY_DRIVER */
  2530.  
  2531.  
  2532. /* **************************************************************** */
  2533. /*                                    */
  2534. /*            Utility Functions                */
  2535. /*                                    */
  2536. /* **************************************************************** */
  2537.  
  2538. /* Return 0 if C is not a member of the class of characters that belong
  2539.    in words, or 1 if it is. */
  2540.  
  2541. int allow_pathname_alphabetic_chars = 0;
  2542. char *pathname_alphabetic_chars = "/-_=~.#$";
  2543.  
  2544. int
  2545. alphabetic (int c)
  2546. {
  2547.   if (pure_alphabetic (c) || (numeric (c)))
  2548.     return (1);
  2549.  
  2550.   if (allow_pathname_alphabetic_chars)
  2551.     return ((int)strrchr (pathname_alphabetic_chars, c));
  2552.   else
  2553.     return (0);
  2554. }
  2555.  
  2556. /* Return non-zero if C is a numeric character. */
  2557. int
  2558. numeric (int c)
  2559. {
  2560.   return (c >= '0' && c <= '9');
  2561. }
  2562.  
  2563. /* Ring the terminal bell. */
  2564. int
  2565. ding (void)
  2566. {
  2567.   if (readline_echoing_p)
  2568.     {
  2569.       if (prefer_visible_bell && visible_bell)
  2570.     tputs (visible_bell, 1, output_character_function);
  2571.       else
  2572.     {
  2573.       fprintf (stderr, "\007");
  2574.       fflush (stderr);
  2575.     }
  2576.     }
  2577.   return (-1);
  2578. }
  2579.  
  2580. /* How to abort things. */
  2581. void rl_abort (int dum1, int dum2)
  2582. {
  2583.   ding ();
  2584.   rl_clear_message ();
  2585.   rl_init_argument ();
  2586.   rl_pending_input = 0;
  2587.  
  2588.   defining_kbd_macro = 0;
  2589.   while (executing_macro)
  2590.     pop_executing_macro ();
  2591.  
  2592.   rl_last_func = (KFunction *)NULL;
  2593.   longjmp (readline_top_level, 1);
  2594. }
  2595.  
  2596. /* Return a copy of the string between FROM and TO.
  2597.    FROM is inclusive, TO is not. */
  2598. #if defined (sun) /* Yes, that's right, some crufty function in sunview is
  2599.              called rl_copy (). */
  2600. static
  2601. #endif
  2602. char *
  2603. rl_copy (int from, int to)
  2604. {
  2605.   register int length;
  2606.   char *copy;
  2607.  
  2608.   /* Fix it if the caller is confused. */
  2609.   if (from > to) {
  2610.     int t = from;
  2611.     from = to;
  2612.     to = t;
  2613.   }
  2614.  
  2615.   length = to - from;
  2616.   copy = (char *)xmalloc (1 + length);
  2617.   strncpy (copy, the_line + from, length);
  2618.   copy[length] = '\0';
  2619.   return (copy);
  2620. }
  2621.  
  2622.  
  2623. /* **************************************************************** */
  2624. /*                                    */
  2625. /*            Insert and Delete                */
  2626. /*                                    */
  2627. /* **************************************************************** */
  2628.  
  2629. /* Insert a string of text into the line at point.  This is the only
  2630.    way that you should do insertion.  rl_insert () calls this
  2631.    function. */
  2632. void rl_insert_text (char *string)
  2633. {
  2634.   extern int doing_an_undo;
  2635.   register int i, l = strlen (string);
  2636.   while (rl_end + l >= rl_line_buffer_len)
  2637.     {
  2638.       rl_line_buffer =
  2639.     (char *)xrealloc (rl_line_buffer,
  2640.               rl_line_buffer_len += DEFAULT_BUFFER_SIZE);
  2641.       the_line = rl_line_buffer;
  2642.     }
  2643.  
  2644.   for (i = rl_end; i >= rl_point; i--)
  2645.     the_line[i + l] = the_line[i];
  2646.   strncpy (the_line + rl_point, string, l);
  2647.  
  2648.   /* Remember how to undo this if we aren't undoing something. */
  2649.   if (!doing_an_undo)
  2650.     {
  2651.       /* If possible and desirable, concatenate the undos. */
  2652.       if ((strlen (string) == 1) &&
  2653.       rl_undo_list &&
  2654.       (rl_undo_list->what == UNDO_INSERT) &&
  2655.       (rl_undo_list->end == rl_point) &&
  2656.       (rl_undo_list->end - rl_undo_list->start < 20))
  2657.     rl_undo_list->end++;
  2658.       else
  2659.     rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
  2660.     }
  2661.   rl_point += l;
  2662.   rl_end += l;
  2663.   the_line[rl_end] = '\0';
  2664. }
  2665.  
  2666. /* Delete the string between FROM and TO.  FROM is
  2667.    inclusive, TO is not. */
  2668. void rl_delete_text (int from, int to)
  2669. {
  2670.   extern int doing_an_undo;
  2671.   register char *text;
  2672.  
  2673.   /* Fix it if the caller is confused. */
  2674.   if (from > to)
  2675.     {
  2676.       int t = from;
  2677.       from = to;
  2678.       to = t;
  2679.     }
  2680.   text = rl_copy (from, to);
  2681.   strncpy (the_line + from, the_line + to, rl_end - to);
  2682.  
  2683.   /* Remember how to undo this delete. */
  2684.   if (!doing_an_undo)
  2685.     rl_add_undo (UNDO_DELETE, from, to, text);
  2686.   else
  2687.     free (text);
  2688.  
  2689.   rl_end -= (to - from);
  2690.   the_line[rl_end] = '\0';
  2691. }
  2692.  
  2693.  
  2694. /* **************************************************************** */
  2695. /*                                    */
  2696. /*            Readline character functions            */
  2697. /*                                    */
  2698. /* **************************************************************** */
  2699.  
  2700. /* This is not a gap editor, just a stupid line input routine.  No hair
  2701.    is involved in writing any of the functions, and none should be. */
  2702.  
  2703. /* Note that:
  2704.  
  2705.    rl_end is the place in the string that we would place '\0';
  2706.    i.e., it is always safe to place '\0' there.
  2707.  
  2708.    rl_point is the place in the string where the cursor is.  Sometimes
  2709.    this is the same as rl_end.
  2710.  
  2711.    Any command that is called interactively receives two arguments.
  2712.    The first is a count: the numeric arg pased to this command.
  2713.    The second is the key which invoked this command.
  2714. */
  2715.  
  2716.  
  2717. /* **************************************************************** */
  2718. /*                                    */
  2719. /*            Movement Commands                */
  2720. /*                                    */
  2721. /* **************************************************************** */
  2722.  
  2723. /* Note that if you `optimize' the display for these functions, you cannot
  2724.    use said functions in other functions which do not do optimizing display.
  2725.    I.e., you will have to update the data base for rl_redisplay, and you
  2726.    might as well let rl_redisplay do that job. */
  2727.  
  2728. /* Move forward COUNT characters. */
  2729. void rl_forward (int count, int dum2)
  2730. {
  2731.   if (count < 0)
  2732.     rl_backward (-count, 0);
  2733.   else
  2734.     while (count)
  2735.       {
  2736. #ifdef VI_MODE
  2737.     if (rl_point == (rl_end - (rl_editing_mode == vi_mode)))
  2738. #else
  2739.     if (rl_point == rl_end)
  2740. #endif
  2741.       {
  2742.         ding ();
  2743.         return;
  2744.       }
  2745.     else
  2746.       rl_point++;
  2747.     --count;
  2748.       }
  2749. }
  2750.  
  2751. /* Move backward COUNT characters. */
  2752. void rl_backward (int count, int dum2)
  2753. {
  2754.   if (count < 0)
  2755.     rl_forward (-count, 0);
  2756.   else
  2757.     while (count)
  2758.       {
  2759.     if (!rl_point)
  2760.       {
  2761.         ding ();
  2762.         return;
  2763.       }
  2764.     else
  2765.       --rl_point;
  2766.     --count;
  2767.       }
  2768. }
  2769.  
  2770. /* Move to the beginning of the line. */
  2771. void rl_beg_of_line (int dum1, int dum2)
  2772. {
  2773.   rl_point = 0;
  2774. }
  2775.  
  2776. /* Move to the end of the line. */
  2777. void rl_end_of_line (int dum1, int dum2)
  2778. {
  2779.   rl_point = rl_end;
  2780. }
  2781.  
  2782. /* Move forward a word.  We do what Emacs does. */
  2783. void rl_forward_word (int count, int dum2)
  2784. {
  2785.   int c;
  2786.  
  2787.   if (count < 0)
  2788.     {
  2789.       rl_backward_word (-count, 0);
  2790.       return;
  2791.     }
  2792.  
  2793.   while (count)
  2794.     {
  2795.       if (rl_point == rl_end)
  2796.     return;
  2797.  
  2798.       /* If we are not in a word, move forward until we are in one.
  2799.      Then, move forward until we hit a non-alphabetic character. */
  2800.       c = the_line[rl_point];
  2801.       if (!alphabetic (c))
  2802.     {
  2803.       while (++rl_point < rl_end)
  2804.         {
  2805.           c = the_line[rl_point];
  2806.           if (alphabetic (c)) break;
  2807.         }
  2808.     }
  2809.       if (rl_point == rl_end) return;
  2810.       while (++rl_point < rl_end)
  2811.     {
  2812.       c = the_line[rl_point];
  2813.       if (!alphabetic (c)) break;
  2814.     }
  2815.       --count;
  2816.     }
  2817. }
  2818.  
  2819. /* Move backward a word.  We do what Emacs does. */
  2820. void rl_backward_word (int count, int dum2)
  2821. {
  2822.   int c;
  2823.  
  2824.   if (count < 0)
  2825.     {
  2826.       rl_forward_word (-count, 0);
  2827.       return;
  2828.     }
  2829.  
  2830.   while (count)
  2831.     {
  2832.       if (!rl_point)
  2833.     return;
  2834.  
  2835.       /* Like rl_forward_word (), except that we look at the characters
  2836.      just before point. */
  2837.  
  2838.       c = the_line[rl_point - 1];
  2839.       if (!alphabetic (c))
  2840.     {
  2841.       while (--rl_point)
  2842.         {
  2843.           c = the_line[rl_point - 1];
  2844.           if (alphabetic (c)) break;
  2845.         }
  2846.     }
  2847.  
  2848.       while (rl_point)
  2849.     {
  2850.       c = the_line[rl_point - 1];
  2851.       if (!alphabetic (c))
  2852.         break;
  2853.       else --rl_point;
  2854.     }
  2855.       --count;
  2856.     }
  2857. }
  2858.  
  2859. /* Clear the current line.  Numeric argument to C-l does this. */
  2860. void rl_refresh_line (int dum1, int dum2)
  2861. {
  2862.   int curr_line = last_c_pos / screenwidth;
  2863.  
  2864.   move_vert(curr_line);
  2865.   move_cursor_relative (0, the_line);   /* XXX is this right */
  2866.  
  2867.   if (term_clreol)
  2868.     tputs (term_clreol, 1, output_character_function);
  2869.  
  2870.   rl_forced_update_display ();
  2871.   rl_display_fixed = 1;
  2872. }
  2873.  
  2874. /* C-l typed to a line without quoting clears the screen, and then reprints
  2875.    the prompt and the current input line.  Given a numeric arg, redraw only
  2876.    the current line. */
  2877. void rl_clear_screen (int dum1, int dum2)
  2878. {
  2879.   if (rl_explicit_arg)
  2880.     {
  2881.       rl_refresh_line (0, 0);
  2882.       return;
  2883.     }
  2884.  
  2885.   if (term_clrpag)
  2886.     tputs (term_clrpag, 1, output_character_function);
  2887.   else
  2888.     crlf ();
  2889.  
  2890.   rl_forced_update_display ();
  2891.   rl_display_fixed = 1;
  2892. }
  2893.  
  2894. void rl_arrow_keys(int count, int c)
  2895. {
  2896.   int ch = rl_read_key();
  2897.  
  2898.   switch(ch) {
  2899.     case 'a':
  2900.     case 'A':
  2901.       rl_get_previous_history(count, 0);
  2902.       return;
  2903.     case 'b':
  2904.     case 'B':
  2905.       rl_get_next_history(count, 0);
  2906.       return;
  2907.     case 'c':
  2908.     case 'C':
  2909.       rl_forward(count, 0);
  2910.       return;
  2911.     case 'd':
  2912.     case 'D':
  2913.       rl_backward(count, 0);
  2914.       return;
  2915.     default:
  2916.       ding();
  2917.       return;
  2918.   }
  2919. }
  2920.  
  2921.  
  2922. /* **************************************************************** */
  2923. /*                                    */
  2924. /*            Text commands                    */
  2925. /*                                    */
  2926. /* **************************************************************** */
  2927.  
  2928. /* Insert the character C at the current location, moving point forward. */
  2929. void rl_insert (int count, int c)
  2930. {
  2931.   register int i;
  2932.   char *string;
  2933.  
  2934.   if (count <= 0)
  2935.     return;
  2936.  
  2937.   /* If we can optimize, then do it.  But don't let people crash
  2938.      readline because of extra large arguments. */
  2939.   if (count > 1 && count < 1024)
  2940.     {
  2941.       string = (char *)alloca (1 + count);
  2942.  
  2943.       for (i = 0; i < count; i++)
  2944.     string[i] = c;
  2945.  
  2946.       string[i] = '\0';
  2947.       rl_insert_text (string);
  2948.       return;
  2949.     }
  2950.  
  2951.   if (count > 1024)
  2952.     {
  2953.       int decreaser;
  2954.  
  2955.       string = (char *)alloca (1024 + 1);
  2956.  
  2957.       for (i = 0; i < 1024; i++)
  2958.     string[i] = c;
  2959.  
  2960.       while (count)
  2961.     {
  2962.       decreaser = (count > 1024 ? 1024 : count);
  2963.       string[decreaser] = '\0';
  2964.       rl_insert_text (string);
  2965.       count -= decreaser;
  2966.     }
  2967.       return;
  2968.     }
  2969.  
  2970.   /* We are inserting a single character.
  2971.      If there is pending input, then make a string of all of the
  2972.      pending characters that are bound to rl_insert, and insert
  2973.      them all. */
  2974.   if (any_typein)
  2975.     {
  2976.       int key = 0, t;
  2977.  
  2978.       i = 0;
  2979.       string = (char *)alloca (ibuffer_len + 1);
  2980.       string[i++] = c;
  2981.  
  2982.       while ((t = rl_get_char (&key)) &&
  2983.          (keymap[key].type == ISFUNC &&
  2984.           keymap[key].function == rl_insert))
  2985.     string[i++] = key;
  2986.  
  2987.       if (t)
  2988.     rl_unget_char (key);
  2989.  
  2990.       string[i] = '\0';
  2991.       rl_insert_text (string);
  2992.       return;
  2993.     }
  2994.   else
  2995.     {
  2996.       /* Inserting a single character. */
  2997.       string = (char *)alloca (2);
  2998.  
  2999.       string[1] = '\0';
  3000.       string[0] = c;
  3001.       rl_insert_text (string);
  3002.     }
  3003. }
  3004.  
  3005. /* Insert the next typed character verbatim. */
  3006. void rl_quoted_insert (int count, int dum2)
  3007. {
  3008.   int c = rl_read_key ();
  3009.   rl_insert (count, c);
  3010. }
  3011.  
  3012. /* Insert a tab character. */
  3013. void rl_tab_insert (int count, int dum2)
  3014. {
  3015.   rl_insert (count, '\t');
  3016. }
  3017.  
  3018. /* What to do when a NEWLINE is pressed.  We accept the whole line.
  3019.    KEY is the key that invoked this command.  I guess it could have
  3020.    meaning in the future. */
  3021. void rl_newline (int count, int key)
  3022. {
  3023.  
  3024.   rl_done = 1;
  3025.  
  3026. #ifdef VI_MODE
  3027.   {
  3028.     extern int vi_doing_insert;
  3029.     if (vi_doing_insert)
  3030.       {
  3031.     rl_end_undo_group ();
  3032.     vi_doing_insert = 0;
  3033.       }
  3034.   }
  3035. #endif /* VI_MODE */
  3036.  
  3037.   if (readline_echoing_p)
  3038.     {
  3039.       move_vert (vis_botlin);
  3040.       vis_botlin = 0;
  3041.       crlf ();
  3042.       fflush (out_stream);
  3043.       rl_display_fixed++;
  3044.     }
  3045. }
  3046.  
  3047. void rl_clean_up_for_exit (void)
  3048. {
  3049.   if (readline_echoing_p)
  3050.     {
  3051.       move_vert (vis_botlin);
  3052.       vis_botlin = 0;
  3053.       fflush (out_stream);
  3054.       rl_restart_output (0, 0);
  3055.     }
  3056. }
  3057.  
  3058. /* What to do for some uppercase characters, like meta characters,
  3059.    and some characters appearing in emacs_ctlx_keymap.  This function
  3060.    is just a stub, you bind keys to it and the code in rl_dispatch ()
  3061.    is special cased. */
  3062. void rl_do_lowercase_version (int ignore1, int ignore2)
  3063. {
  3064. }
  3065.  
  3066. /* Rubout the character behind point. */
  3067. void rl_rubout (int count, int dummy)
  3068. {
  3069.   if (count < 0)
  3070.     {
  3071.       rl_delete (-count, 0);
  3072.       return;
  3073.     }
  3074.  
  3075.   if (!rl_point)
  3076.     {
  3077.       ding ();
  3078.       return;
  3079.     }
  3080.  
  3081.   if (count > 1)
  3082.     {
  3083.       int orig_point = rl_point;
  3084.       rl_backward (count, 0);
  3085.       rl_kill_text (orig_point, rl_point);
  3086.     }
  3087.   else
  3088.     {
  3089.       int c = the_line[--rl_point];
  3090.       rl_delete_text (rl_point, rl_point + 1);
  3091.  
  3092.       if (rl_point == rl_end && alphabetic (c) && last_c_pos)
  3093.     {
  3094.       backspace (1);
  3095.       putc (' ', out_stream);
  3096.       backspace (1);
  3097.       last_c_pos--;
  3098.       visible_line[last_c_pos] = '\0';
  3099.       rl_display_fixed++;
  3100.     }
  3101.     }
  3102. }
  3103.  
  3104. /* Delete the character under the cursor.  Given a numeric argument,
  3105.    kill that many characters instead. */
  3106. void rl_delete (int count, int invoking_key)
  3107. {
  3108.   if (count < 0)
  3109.     {
  3110.       rl_rubout (-count, 0);
  3111.       return;
  3112.     }
  3113.  
  3114.   if (rl_point == rl_end)
  3115.     {
  3116.       ding ();
  3117.       return;
  3118.     }
  3119.  
  3120.   if (count > 1)
  3121.     {
  3122.       int orig_point = rl_point;
  3123.       rl_forward (count, 0);
  3124.       rl_kill_text (orig_point, rl_point);
  3125.       rl_point = orig_point;
  3126.     }
  3127.   else
  3128.     rl_delete_text (rl_point, rl_point + 1);
  3129. }
  3130.  
  3131.  
  3132. /* **************************************************************** */
  3133. /*                                    */
  3134. /*            Kill commands                    */
  3135. /*                                    */
  3136. /* **************************************************************** */
  3137.  
  3138. /* The next two functions mimic unix line editing behaviour, except they
  3139.    save the deleted text on the kill ring.  This is safer than not saving
  3140.    it, and since we have a ring, nobody should get screwed. */
  3141.  
  3142. /* This does what C-w does in Unix.  We can't prevent people from
  3143.    using behaviour that they expect. */
  3144. void rl_unix_word_rubout (int dum1, int dum2)
  3145. {
  3146.   if (!rl_point) ding ();
  3147.   else {
  3148.     int orig_point = rl_point;
  3149.     while (rl_point && whitespace (the_line[rl_point - 1]))
  3150.       rl_point--;
  3151.     while (rl_point && !whitespace (the_line[rl_point - 1]))
  3152.       rl_point--;
  3153.     rl_kill_text (rl_point, orig_point);
  3154.   }
  3155. }
  3156.  
  3157. /* Here is C-u doing what Unix does.  You don't *have* to use these
  3158.    key-bindings.  We have a choice of killing the entire line, or
  3159.    killing from where we are to the start of the line.  We choose the
  3160.    latter, because if you are a Unix weenie, then you haven't backspaced
  3161.    into the line at all, and if you aren't, then you know what you are
  3162.    doing. */
  3163. void rl_unix_line_discard (int dummy1, int dummy2)
  3164. {
  3165.   if (!rl_point) 
  3166.     ding ();
  3167.   else {
  3168.     rl_kill_text (rl_point, 0);
  3169.     rl_point = 0;
  3170.   }
  3171. }
  3172.  
  3173.  
  3174.  
  3175. /* **************************************************************** */
  3176. /*                                    */
  3177. /*            Commands For Typos                */
  3178. /*                                    */
  3179. /* **************************************************************** */
  3180.  
  3181. /* Random and interesting things in here.  */
  3182.  
  3183. /* **************************************************************** */
  3184. /*                                    */
  3185. /*            Changing Case                    */
  3186. /*                                    */
  3187. /* **************************************************************** */
  3188.  
  3189. /* The three kinds of things that we know how to do. */
  3190. #define UpCase 1
  3191. #define DownCase 2
  3192. #define CapCase 3
  3193.  
  3194. /* Uppercase the word at point. */
  3195. void rl_upcase_word (int count, int dum2)
  3196. {
  3197.   rl_change_case (count, UpCase);
  3198. }
  3199.  
  3200. /* Lowercase the word at point. */
  3201. void rl_downcase_word (int count, int dum2)
  3202. {
  3203.   rl_change_case (count, DownCase);
  3204. }
  3205.  
  3206. /* Upcase the first letter, downcase the rest. */
  3207. void rl_capitalize_word (int count, int dum2)
  3208. {
  3209.   rl_change_case (count, CapCase);
  3210. }
  3211.  
  3212. /* The meaty function.
  3213.    Change the case of COUNT words, performing OP on them.
  3214.    OP is one of UpCase, DownCase, or CapCase.
  3215.    If a negative argument is given, leave point where it started,
  3216.    otherwise, leave it where it moves to. */
  3217. void rl_change_case (int count, int op)
  3218. {
  3219.   register int start = rl_point, end;
  3220.   int state = 0;
  3221.  
  3222.   rl_forward_word (count, 0);
  3223.   end = rl_point;
  3224.  
  3225.   if (count < 0)
  3226.     {
  3227.       int temp = start;
  3228.       start = end;
  3229.       end = temp;
  3230.     }
  3231.  
  3232.   /* We are going to modify some text, so let's prepare to undo it. */
  3233.   rl_modifying (start, end);
  3234.  
  3235.   for (; start < end; start++)
  3236.     {
  3237.       switch (op)
  3238.     {
  3239.     case UpCase:
  3240.       the_line[start] = to_upper (the_line[start]);
  3241.       break;
  3242.  
  3243.     case DownCase:
  3244.       the_line[start] = to_lower (the_line[start]);
  3245.       break;
  3246.  
  3247.     case CapCase:
  3248.       if (state == 0)
  3249.         {
  3250.           the_line[start] = to_upper (the_line[start]);
  3251.           state = 1;
  3252.         }
  3253.       else
  3254.         {
  3255.           the_line[start] = to_lower (the_line[start]);
  3256.         }
  3257.       if (!pure_alphabetic (the_line[start]))
  3258.         state = 0;
  3259.       break;
  3260.  
  3261.     default:
  3262.       abort ();
  3263.     }
  3264.     }
  3265.   rl_point = end;
  3266. }
  3267.  
  3268. /* **************************************************************** */
  3269. /*                                    */
  3270. /*            Transposition                    */
  3271. /*                                    */
  3272. /* **************************************************************** */
  3273.  
  3274. /* Transpose the words at point. */
  3275. void rl_transpose_words (int count, int dum2)
  3276. {
  3277.   char *word1, *word2;
  3278.   int w1_beg, w1_end, w2_beg, w2_end;
  3279.   int orig_point = rl_point;
  3280.  
  3281.   if (!count) return;
  3282.  
  3283.   /* Find the two words. */
  3284.   rl_forward_word (count, 0);
  3285.   w2_end = rl_point;
  3286.   rl_backward_word (1, 0);
  3287.   w2_beg = rl_point;
  3288.   rl_backward_word (count, 0);
  3289.   w1_beg = rl_point;
  3290.   rl_forward_word (1, 0);
  3291.   w1_end = rl_point;
  3292.  
  3293.   /* Do some check to make sure that there really are two words. */
  3294.   if ((w1_beg == w2_beg) || (w2_beg < w1_end))
  3295.     {
  3296.       ding ();
  3297.       rl_point = orig_point;
  3298.       return;
  3299.     }
  3300.  
  3301.   /* Get the text of the words. */
  3302.   word1 = rl_copy (w1_beg, w1_end);
  3303.   word2 = rl_copy (w2_beg, w2_end);
  3304.  
  3305.   /* We are about to do many insertions and deletions.  Remember them
  3306.      as one operation. */
  3307.   rl_begin_undo_group ();
  3308.  
  3309.   /* Do the stuff at word2 first, so that we don't have to worry
  3310.      about word1 moving. */
  3311.   rl_point = w2_beg;
  3312.   rl_delete_text (w2_beg, w2_end);
  3313.   rl_insert_text (word1);
  3314.  
  3315.   rl_point = w1_beg;
  3316.   rl_delete_text (w1_beg, w1_end);
  3317.   rl_insert_text (word2);
  3318.  
  3319.   /* This is exactly correct since the text before this point has not
  3320.      changed in length. */
  3321.   rl_point = w2_end;
  3322.  
  3323.   /* I think that does it. */
  3324.   rl_end_undo_group ();
  3325.   free (word1); free (word2);
  3326. }
  3327.  
  3328. /* Transpose the characters at point.  If point is at the end of the line,
  3329.    then transpose the characters before point. */
  3330. void rl_transpose_chars (int count, int dum2)
  3331. {
  3332.   if (!count)
  3333.     return;
  3334.  
  3335.   if (!rl_point || rl_end < 2) {
  3336.     ding ();
  3337.     return;
  3338.   }
  3339.  
  3340.   while (count) {
  3341.     if (rl_point == rl_end) {
  3342.       int t = the_line[rl_point - 1];
  3343.       the_line[rl_point - 1] = the_line[rl_point - 2];
  3344.       the_line[rl_point - 2] = t;
  3345.     } else {
  3346.       int t = the_line[rl_point];
  3347.       the_line[rl_point] = the_line[rl_point - 1];
  3348.       the_line[rl_point - 1] = t;
  3349.       if (count < 0 && rl_point)
  3350.     rl_point--;
  3351.       else
  3352.     rl_point++;
  3353.     }
  3354.     if (count < 0)
  3355.       count++;
  3356.     else
  3357.       count--;
  3358.   }
  3359. }
  3360.  
  3361.  
  3362. /* **************************************************************** */
  3363. /*                                    */
  3364. /*            Bogus Flow Control                  */
  3365. /*                                    */
  3366. /* **************************************************************** */
  3367.  
  3368. void rl_restart_output (int count, int key)
  3369. {
  3370.   int fildes = fileno (stdin);
  3371. #if defined (TIOCSTART)
  3372. #if defined (apollo)
  3373.   ioctl (&fildes, TIOCSTART, 0);
  3374. #else
  3375.   ioctl (fildes, TIOCSTART, 0);
  3376. #endif /* apollo */
  3377.  
  3378. #else
  3379. #  if defined (TCXONC)
  3380.   ioctl (fildes, TCXONC, TCOON);
  3381. #  endif /* TCXONC */
  3382. #endif /* TIOCSTART */
  3383. }
  3384.  
  3385. /* **************************************************************** */
  3386. /*                                    */
  3387. /*    Completion matching, from readline's point of view.        */
  3388. /*                                    */
  3389. /* **************************************************************** */
  3390.  
  3391. /* Pointer to the generator function for completion_matches ().
  3392.    NULL means to use filename_entry_function (), the default filename
  3393.    completer. */
  3394. CFunction *rl_completion_entry_function = (CFunction *)NULL;
  3395.  
  3396. /* Pointer to alternative function to create matches.
  3397.    Function is called with TEXT, START, and END.
  3398.    START and END are indices in RL_LINE_BUFFER saying what the boundaries
  3399.    of TEXT are.
  3400.    If this function exists and returns NULL then call the value of
  3401.    rl_completion_entry_function to try to match, otherwise use the
  3402.    array of strings returned. */
  3403.  
  3404. UFunction *rl_attempted_completion_function = (UFunction *)NULL;
  3405.  
  3406. /* Complete the word at or before point.  You have supplied the function
  3407.    that does the initial simple matching selection algorithm (see
  3408.    completion_matches ()).  The default is to do filename completion. */
  3409. void rl_complete (int ignore, int invoking_key)
  3410. {
  3411.   if (rl_last_func == rl_complete)
  3412.     rl_complete_internal ('?');
  3413.   else
  3414.     rl_complete_internal (TAB);
  3415. }
  3416.  
  3417. /* List the possible completions.  See description of rl_complete (). */
  3418. void rl_possible_completions (int dum1, int dum2)
  3419. {
  3420.   rl_complete_internal ('?');
  3421. }
  3422.  
  3423. /* The user must press "y" or "n". Non-zero return means "y" pressed. */
  3424. int get_y_or_n (void)
  3425. {
  3426.   int c;
  3427.  loop:
  3428.   c = rl_read_key ();
  3429.   if (c == 'y' || c == 'Y') return (1);
  3430.   if (c == 'n' || c == 'N') return (0);
  3431.   if (c == ABORT_CHAR) rl_abort (0, 0);
  3432.   ding (); goto loop;
  3433. }
  3434.  
  3435. /* Up to this many items will be displayed in response to a
  3436.    possible-completions call.  After that, we ask the user if
  3437.    she is sure she wants to see them all. */
  3438. int rl_completion_query_items = 100;
  3439.  
  3440. /* The basic list of characters that signal a break between words for the
  3441.    completer routine.  The contents of this variable is what breaks words
  3442.    in the shell, i.e. " \t\n\"\\'`@$><=" */
  3443. char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=";
  3444.  
  3445. /* The list of characters that signal a break between words for
  3446.    rl_complete_internal.  The default list is the contents of
  3447.    rl_basic_word_break_characters.  */
  3448. char *rl_completer_word_break_characters = (char *)NULL;
  3449.  
  3450. /* List of characters that are word break characters, but should be left
  3451.    in TEXT when it is passed to the completion function.  The shell uses
  3452.    this to help determine what kind of completing to do. */
  3453. char *rl_special_prefixes = (char *)NULL;
  3454.  
  3455. /* If non-zero, then disallow duplicates in the matches. */
  3456. int rl_ignore_completion_duplicates = 1;
  3457.  
  3458. /* Non-zero means that the results of the matches are to be treated
  3459.    as filenames.  This is ALWAYS zero on entry, and can only be changed
  3460.    within a completion entry finder function. */
  3461. int rl_filename_completion_desired = 0;
  3462.  
  3463. /* This function, if defined, is called by the completer when real
  3464.    filename completion is done, after all the matching names have been
  3465.    generated. It is passed a (char**) known as matches in the code below.
  3466.    It consists of a NULL-terminated array of pointers to potential
  3467.    matching strings.  The 1st element (matches[0]) is the maximal
  3468.    substring that is common to all matches. This function can re-arrange
  3469.    the list of matches as required, but all elements of the array must be
  3470.    free()'d if they are deleted. The main intent of this function is
  3471.    to implement FIGNORE a la SunOS csh. */
  3472. CCFunction *rl_ignore_some_completions_function = (CCFunction *) NULL;
  3473.  
  3474. /* Complete the word at or before point.
  3475.    WHAT_TO_DO says what to do with the completion.
  3476.    `?' means list the possible completions.
  3477.    TAB means do standard completion.
  3478.    `*' means insert all of the possible completions. */
  3479. void rl_complete_internal (int what_to_do)
  3480. {
  3481.   char **matches;
  3482.   CFunction *our_func;
  3483.   int start, end, delimiter = 0;
  3484.   char *text;
  3485.  
  3486.   if (rl_completion_entry_function)
  3487.     our_func = rl_completion_entry_function;
  3488.   else
  3489.     our_func = (CFunction *)filename_completion_function;
  3490.  
  3491.   /* Only the completion entry function can change this. */
  3492.   rl_filename_completion_desired = 0;
  3493.  
  3494.   /* We now look backwards for the start of a filename/variable word. */
  3495.   end = rl_point;
  3496.  
  3497.   if (rl_point)
  3498.     {
  3499.       while (--rl_point &&
  3500.          !strrchr (rl_completer_word_break_characters, the_line[rl_point]));
  3501.  
  3502.       /* If we are at a word break, then advance past it. */
  3503.       if (strrchr (rl_completer_word_break_characters,  (the_line[rl_point])))
  3504.     {
  3505.       /* If the character that caused the word break was a quoting
  3506.          character, then remember it as the delimiter. */
  3507.       if (strrchr ("\"'", the_line[rl_point]) && (end - rl_point) > 1)
  3508.         delimiter = the_line[rl_point];
  3509.  
  3510.       /* If the character isn't needed to determine something special
  3511.          about what kind of completion to perform, then advance past it. */
  3512.  
  3513.       if (!rl_special_prefixes ||
  3514.           !strrchr (rl_special_prefixes, the_line[rl_point]))
  3515.         rl_point++;
  3516.     }
  3517.     }
  3518.  
  3519.   start = rl_point;
  3520.   rl_point = end;
  3521.   text = rl_copy (start, end);
  3522.  
  3523.   /* If the user wants to TRY to complete, but then wants to give
  3524.      up and use the default completion function, they set the
  3525.      variable rl_attempted_completion_function. */
  3526.   if (rl_attempted_completion_function)
  3527.     {
  3528.       matches =
  3529.     (char **)(*rl_attempted_completion_function) (text, start, end);
  3530.  
  3531.       if (matches)
  3532.     {
  3533.       our_func = (CFunction *)NULL;
  3534.       goto after_usual_completion;
  3535.     } 
  3536.     }
  3537.  
  3538.   matches = completion_matches (text, our_func);
  3539.  
  3540.  after_usual_completion:
  3541.   free (text);
  3542.  
  3543.   if (!matches)
  3544.     ding ();
  3545.   else
  3546.     {
  3547.       register int i;
  3548.  
  3549.       /* It seems to me that in all the cases we handle we would like
  3550.      to ignore duplicate possiblilities.  Scan for the text to
  3551.      insert being identical to the other completions. */
  3552.       if (rl_ignore_completion_duplicates)
  3553.     {
  3554.       char *lowest_common;
  3555.       int j, newlen = 0;
  3556.  
  3557.       /* Sort the items. */
  3558.       /* It is safe to sort this array, because the lowest common
  3559.          denominator found in matches[0] will remain in place. */
  3560.       for (i = 0; matches[i]; i++)
  3561.         ;
  3562.       qsort (matches, i, sizeof (char *), compare_strings);
  3563.  
  3564.       /* Remember the lowest common denominator for it may be unique. */
  3565.       lowest_common = savestring (matches[0]);
  3566.  
  3567.       for (i = 0; matches[i + 1]; i++)
  3568.         {
  3569.           if (strcmp (matches[i], matches[i + 1]) == 0)
  3570.         {
  3571.           free (matches[i]);
  3572.           matches[i] = (char *)-1;
  3573.         }
  3574.           else
  3575.         newlen++;
  3576.         }
  3577.  
  3578.       /* We have marked all the dead slots with (char *)-1.
  3579.          Copy all the non-dead entries into a new array. */
  3580.       {
  3581.         char **temp_array =
  3582.           (char **)malloc ((3 + newlen) * sizeof (char *));
  3583.  
  3584.         for (i = 1, j = 1; matches[i]; i++)
  3585.           {
  3586.         if (matches[i] != (char *)-1)
  3587.           temp_array[j++] = matches[i];
  3588.           }
  3589.  
  3590.         temp_array[j] = (char *)NULL;
  3591.  
  3592.         if (matches[0] != (char *)-1)
  3593.           free (matches[0]);
  3594.  
  3595.         free (matches);
  3596.  
  3597.         matches = temp_array;
  3598.       }
  3599.  
  3600.       /* Place the lowest common denominator back in [0]. */
  3601.       matches[0] = lowest_common;
  3602.  
  3603.       /* If there is one string left, and it is identical to the
  3604.          lowest common denominator, then the LCD is the string to
  3605.          insert. */
  3606.       if (j == 2 && strcmp (matches[0], matches[1]) == 0)
  3607.         {
  3608.           free (matches[1]);
  3609.           matches[1] = (char *)NULL;
  3610.         }
  3611.     }
  3612.  
  3613.       switch (what_to_do)
  3614.     {
  3615.     case TAB:
  3616.       /* If we are matching filenames, then here is our chance to
  3617.          do clever processing by re-examining the list.  Call the
  3618.          ignore function with the array as a parameter.  It can
  3619.          munge the array, deleting matches as it desires */
  3620.       if (rl_ignore_some_completions_function && 
  3621.           our_func == (CFunction *)filename_completion_function)
  3622.         (void)(*rl_ignore_some_completions_function)(matches);
  3623.       
  3624.       if (matches[0])
  3625.         {
  3626.           rl_delete_text (start, rl_point);
  3627.           rl_point = start;
  3628.           rl_insert_text (matches[0]);
  3629.         }
  3630.       
  3631.       /* If there are more matches, ring the bell to indicate.
  3632.          If this was the only match, and we are hacking files,
  3633.          check the file to see if it was a directory.  If so,
  3634.          add a '/' to the name.  If not, and we are at the end
  3635.          of the line, then add a space. */
  3636.       if (matches[1])
  3637.         {
  3638.           ding ();        /* There are other matches remaining. */
  3639.         }
  3640.       else
  3641.         {
  3642.           char temp_string[2];
  3643.  
  3644.           temp_string[0] = delimiter ? delimiter : ' ';
  3645.           temp_string[1] = '\0';
  3646.  
  3647.           if (rl_filename_completion_desired)
  3648.         {
  3649.           struct stat finfo;
  3650.           char *tilde_expand (char *filename);
  3651.           char *filename = tilde_expand (matches[0]);
  3652.  
  3653. /* What will be the next fashion? */
  3654. #ifndef S_IFMT
  3655. #define S_IFMT _S_IFMT
  3656. #endif
  3657. #ifndef S_IFDIR
  3658. #define S_IFDIR _S_IFDIR
  3659. #endif
  3660.           if ((stat (filename, &finfo) == 0) &&
  3661.               ((finfo.st_mode & S_IFMT) == S_IFDIR))
  3662.             {
  3663.               if (the_line[rl_point] != '/')
  3664.             rl_insert_text ("/");
  3665.             }
  3666.           else
  3667.             {
  3668.               if (rl_point == rl_end)
  3669.             rl_insert_text (temp_string);
  3670.             }
  3671.           free (filename);
  3672.         }
  3673.           else
  3674.         {
  3675.           if (rl_point == rl_end)
  3676.             rl_insert_text (temp_string);
  3677.         }
  3678.         }
  3679.       break;
  3680.  
  3681.     case '*':
  3682.       {
  3683.         int ii = 1;
  3684.  
  3685.         rl_delete_text (start, rl_point);
  3686.         rl_point = start;
  3687.         rl_begin_undo_group ();
  3688.         if (matches[1])
  3689.           {
  3690.         while (matches[ii])
  3691.           {
  3692.             rl_insert_text (matches[ii++]);
  3693.             rl_insert_text (" ");
  3694.           }
  3695.           }
  3696.         else
  3697.           {
  3698.         rl_insert_text (matches[0]);
  3699.         rl_insert_text (" ");
  3700.           }
  3701.         rl_end_undo_group ();
  3702.       }
  3703.       break;
  3704.  
  3705.     case '?':
  3706.       {
  3707.         int len, count, limit, max = 0;
  3708.         int j, k, l;
  3709.  
  3710.         /* Handle simple case first.  What if there is only one answer? */
  3711.         if (!matches[1])
  3712.           {
  3713.         char *temp;
  3714.  
  3715.         if (rl_filename_completion_desired)
  3716.           temp = strrchr (matches[0], '/');
  3717.         else
  3718.           temp = (char *)NULL;
  3719.  
  3720.         if (!temp)
  3721.           temp = matches[0];
  3722.         else
  3723.           temp++;
  3724.  
  3725.         crlf ();
  3726.         fprintf (out_stream, "%s", temp);
  3727.         crlf ();
  3728.         goto restart;
  3729.           }
  3730.  
  3731.         /* There is more than one answer.  Find out how many there are,
  3732.            and find out what the maximum printed length of a single entry
  3733.            is. */
  3734.         for (i = 1; matches[i]; i++)
  3735.           {
  3736.         char *temp = (char *)NULL;
  3737.  
  3738.         /* If we are hacking filenames, then only count the characters
  3739.            after the last slash in the pathname. */
  3740.         if (rl_filename_completion_desired)
  3741.           temp = strrchr (matches[i], '/');
  3742.         else
  3743.           temp = (char *)NULL;
  3744.  
  3745.         if (!temp)
  3746.           temp = matches[i];
  3747.         else
  3748.           temp++;
  3749.  
  3750.         if (strlen (temp) > max)
  3751.           max = strlen (temp);
  3752.           }
  3753.  
  3754.         len = i;
  3755.  
  3756.         /* If there are many items, then ask the user if she
  3757.            really wants to see them all. */
  3758.         if (len >= rl_completion_query_items)
  3759.           {
  3760.         crlf ();
  3761.         fprintf (out_stream,
  3762.              "There are %d possibilities.  Do you really", len);
  3763.         crlf ();
  3764.         fprintf (out_stream, "wish to see them all? (y or n)");
  3765.         fflush (out_stream);
  3766.         if (!get_y_or_n ())
  3767.           {
  3768.             crlf ();
  3769.             goto restart;
  3770.           }
  3771.           }
  3772.         /* How many items of MAX length can we fit in the screen window? */
  3773.         max += 2;
  3774.         limit = screenwidth / max;
  3775.         if (limit != 1 && (limit * max == screenwidth))
  3776.           limit--;
  3777.  
  3778.         /* Avoid a possible floating exception.  If max > screenwidth,
  3779.            limit will be 0 and a divide-by-zero fault will result. */
  3780.         if (limit == 0)
  3781.           limit = 1;
  3782.  
  3783.         /* How many iterations of the printing loop? */
  3784.         count = (len + (limit - 1)) / limit;
  3785.  
  3786.         /* Watch out for special case.  If LEN is less than LIMIT, then
  3787.            just do the inner printing loop. */
  3788.         if (len < limit) count = 1;
  3789.  
  3790.         /* Sort the items if they are not already sorted. */
  3791.         if (!rl_ignore_completion_duplicates)
  3792.           qsort (matches, len, sizeof (char *), compare_strings);
  3793.  
  3794.         /* Print the sorted items, up-and-down alphabetically, like
  3795.            ls might. */
  3796.         crlf ();
  3797.  
  3798.         for (i = 1; i < count + 1; i++)
  3799.           {
  3800.         for (j = 0, l = i; j < limit; j++)
  3801.           {
  3802.             if (l > len || !matches[l])
  3803.               {
  3804.             break;
  3805.               }
  3806.             else
  3807.               {
  3808.             char *temp = (char *)NULL;
  3809.  
  3810.             if (rl_filename_completion_desired)
  3811.               temp = strrchr (matches[l], '/');
  3812.             else
  3813.               temp = (char *)NULL;
  3814.  
  3815.             if (!temp)
  3816.               temp = matches[l];
  3817.             else
  3818.               temp++;
  3819.  
  3820.             fprintf (out_stream, "%s", temp);
  3821.             for (k = 0; k < max - strlen (temp); k++)
  3822.               putc (' ', out_stream);
  3823.               }
  3824.             l += count;
  3825.           }
  3826.         crlf ();
  3827.           }
  3828.       restart:
  3829.  
  3830.         rl_on_new_line ();
  3831.       }
  3832.       break;
  3833.  
  3834.     default:
  3835.       abort ();
  3836.     }
  3837.  
  3838.       for (i = 0; matches[i]; i++) {
  3839.             free (matches[i]);
  3840.       }
  3841.       free (matches);
  3842.     }
  3843. }
  3844.  
  3845. /* Stupid comparison routine for qsort () ing strings. */
  3846. static int
  3847. compare_strings (const void *s1, const void *s2)
  3848. {
  3849.   return (strcmp ((char *) *((char **)s1), (char *) *((char **)s2)));
  3850. }
  3851.  
  3852. /* A completion function for usernames.
  3853.    TEXT contains a partial username preceded by a random
  3854.    character (usually `~').  */
  3855. char *
  3856. username_completion_function (char *text, int state)
  3857. {
  3858.   static char *username = (char *)NULL;
  3859.   static struct passwd *entry;
  3860.   static int namelen, first_char, first_char_loc;
  3861.  
  3862.   if (!state)
  3863.     {
  3864.       if (username)
  3865.     free (username);
  3866.  
  3867.       first_char = *text;
  3868.  
  3869.       if (first_char == '~')
  3870.     first_char_loc = 1;
  3871.       else
  3872.     first_char_loc = 0;
  3873.  
  3874.       username = savestring (&text[first_char_loc]);
  3875.       namelen = strlen (username);
  3876.       setpwent();
  3877.     }
  3878.  
  3879.   while ( (entry = getpwent()) == (struct passwd *)NULL)
  3880.     {
  3881.       if (strncmp (username, entry->pw_name, namelen) == 0)
  3882.     break;
  3883.     }
  3884.  
  3885.   if (!entry)
  3886.     {
  3887.       endpwent ();
  3888.       return ((char *)NULL);
  3889.     }
  3890.   else
  3891.     {
  3892.       char *value = (char *)xmalloc (2 + strlen (entry->pw_name));
  3893.  
  3894.       *value = *text;
  3895.  
  3896.       strcpy (value + first_char_loc, entry->pw_name);
  3897.  
  3898.       if (first_char == '~')
  3899.     rl_filename_completion_desired = 1;
  3900.  
  3901.       return (value);
  3902.     }
  3903. }
  3904.  
  3905. /* If non-null, this contains the address of a function to call if the
  3906.    standard meaning for expanding a tilde fails.  The function is called
  3907.    with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
  3908.    which is the expansion, or a NULL pointer if there is no expansion. */
  3909. char *(*rl_tilde_expander)(char *) = (char *(*)(char *))NULL;
  3910.  
  3911. /* Expand FILENAME if it begins with a tilde.  This always returns
  3912.    a new string. */
  3913. char *
  3914. tilde_expand (char *filename)
  3915. {
  3916.   char *tdirname = filename ? savestring (filename) : (char *)NULL;
  3917.  
  3918.   if (tdirname && *tdirname == '~')
  3919.     {
  3920.       char *temp_name;
  3921.       if (!tdirname[1] || tdirname[1] == '/')
  3922.     {
  3923.       /* Prepend $HOME to the rest of the string. */
  3924.       char *temp_home = (char *)getenv ("HOME");
  3925.  
  3926.       temp_name = (char *)alloca (1 + strlen (&tdirname[1])
  3927.                       + (temp_home? strlen (temp_home) : 0));
  3928.       temp_name[0] = '\0';
  3929.       if (temp_home)
  3930.         strcpy (temp_name, temp_home);
  3931.       strcat (temp_name, &tdirname[1]);
  3932.       free (tdirname);
  3933.       tdirname = savestring (temp_name);
  3934.     }
  3935.       else
  3936.     {
  3937.       struct passwd *getpwnam (const char *), *user_entry;
  3938.       char *username = (char *)alloca (257);
  3939.       int i, c;
  3940.  
  3941.       for (i = 1; c = tdirname[i]; i++)
  3942.         {
  3943.           if (c == '/') break;
  3944.           else username[i - 1] = c;
  3945.         }
  3946.       username[i - 1] = '\0';
  3947.  
  3948.       if (!(user_entry = getpwnam (username)))
  3949.         {
  3950.           /* If the calling program has a special syntax for
  3951.          expanding tildes, and we couldn't find a standard
  3952.          expansion, then let them try. */
  3953.           if (rl_tilde_expander)
  3954.         {
  3955.           char *expansion;
  3956.  
  3957.           expansion = (char *)(*rl_tilde_expander) (username);
  3958.  
  3959.           if (expansion)
  3960.             {
  3961.               temp_name = (char *)alloca (1 + strlen (expansion)
  3962.                           + strlen (&tdirname[i]));
  3963.               strcpy (temp_name, expansion);
  3964.               strcat (temp_name, &tdirname[i]);
  3965.               free (expansion);
  3966.               goto return_name;
  3967.             }
  3968.         }
  3969.           /*
  3970.            * We shouldn't report errors.
  3971.            */
  3972.         }
  3973.       else
  3974.         {
  3975.           temp_name = (char *)alloca (1 + strlen (user_entry->pw_dir)
  3976.                       + strlen (&tdirname[i]));
  3977.           strcpy (temp_name, user_entry->pw_dir);
  3978.           strcat (temp_name, &tdirname[i]);
  3979.         return_name:
  3980.           free (tdirname);
  3981.           tdirname = savestring (temp_name);
  3982.         }
  3983.         endpwent ();
  3984.     }
  3985.     }
  3986.   return (tdirname);
  3987. }
  3988.  
  3989.  
  3990. /* **************************************************************** */
  3991. /*                                    */
  3992. /*            Undo, and Undoing                */
  3993. /*                                    */
  3994. /* **************************************************************** */
  3995.  
  3996. /* Non-zero tells rl_delete_text and rl_insert_text to not add to
  3997.    the undo list. */
  3998. int doing_an_undo = 0;
  3999.  
  4000. /* The current undo list for THE_LINE. */
  4001. UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL;
  4002.  
  4003. /* Remember how to undo something.  Concatenate some undos if that
  4004.    seems right. */
  4005. void rl_add_undo (enum undo_code what, int start, int end, char *text)
  4006. {
  4007.   UNDO_LIST *temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST));
  4008.   temp->what = what;
  4009.   temp->start = start;
  4010.   temp->end = end;
  4011.   temp->text = text;
  4012.   temp->next = rl_undo_list;
  4013.   rl_undo_list = temp;
  4014. }
  4015.  
  4016. /* Free the existing undo list. */
  4017. void free_undo_list (void)
  4018. {
  4019.   while (rl_undo_list) {
  4020.     UNDO_LIST *release = rl_undo_list;
  4021.     rl_undo_list = rl_undo_list->next;
  4022.  
  4023.     if (release->what == UNDO_DELETE)
  4024.       free (release->text);
  4025.  
  4026.     free (release);
  4027.   }
  4028. }
  4029.  
  4030. /* Undo the next thing in the list.  Return 0 if there
  4031.    is nothing to undo, or non-zero if there was. */
  4032. int
  4033. rl_do_undo (void)
  4034. {
  4035.   UNDO_LIST *release;
  4036.   int waiting_for_begin = 0;
  4037.  
  4038. undo_thing:
  4039.   if (!rl_undo_list)
  4040.     return (0);
  4041.  
  4042.   doing_an_undo = 1;
  4043.  
  4044.   switch (rl_undo_list->what) {
  4045.  
  4046.     /* Undoing deletes means inserting some text. */
  4047.   case UNDO_DELETE:
  4048.     rl_point = rl_undo_list->start;
  4049.     rl_insert_text (rl_undo_list->text);
  4050.     free (rl_undo_list->text);
  4051.     break;
  4052.  
  4053.     /* Undoing inserts means deleting some text. */
  4054.   case UNDO_INSERT:
  4055.     rl_delete_text (rl_undo_list->start, rl_undo_list->end);
  4056.     rl_point = rl_undo_list->start;
  4057.     break;
  4058.  
  4059.     /* Undoing an END means undoing everything 'til we get to
  4060.        a BEGIN. */
  4061.   case UNDO_END:
  4062.     waiting_for_begin++;
  4063.     break;
  4064.  
  4065.     /* Undoing a BEGIN means that we are done with this group. */
  4066.   case UNDO_BEGIN:
  4067.     if (waiting_for_begin)
  4068.       waiting_for_begin--;
  4069.     else
  4070.       abort ();
  4071.     break;
  4072.   }
  4073.  
  4074.   doing_an_undo = 0;
  4075.  
  4076.   release = rl_undo_list;
  4077.   rl_undo_list = rl_undo_list->next;
  4078.   free (release);
  4079.  
  4080.   if (waiting_for_begin)
  4081.     goto undo_thing;
  4082.  
  4083.   return (1);
  4084. }
  4085.  
  4086. /* Begin a group.  Subsequent undos are undone as an atomic operation. */
  4087. void rl_begin_undo_group (void)
  4088. {
  4089.   rl_add_undo (UNDO_BEGIN, 0, 0, 0);
  4090. }
  4091.  
  4092. /* End an undo group started with rl_begin_undo_group (). */
  4093. void rl_end_undo_group (void)
  4094. {
  4095.   rl_add_undo (UNDO_END, 0, 0, 0);
  4096. }
  4097.  
  4098. /* Save an undo entry for the text from START to END. */
  4099. void rl_modifying (int start, int end)
  4100. {
  4101.   if (start > end)
  4102.     {
  4103.       int t = start;
  4104.       start = end;
  4105.       end = t;
  4106.     }
  4107.  
  4108.   if (start != end)
  4109.     {
  4110.       char *temp = rl_copy (start, end);
  4111.       rl_begin_undo_group ();
  4112.       rl_add_undo (UNDO_DELETE, start, end, temp);
  4113.       rl_add_undo (UNDO_INSERT, start, end, (char *)NULL);
  4114.       rl_end_undo_group ();
  4115.     }
  4116. }
  4117.  
  4118. /* Revert the current line to its previous state. */
  4119. void rl_revert_line (int dum1, int dum2)
  4120. {
  4121.   if (!rl_undo_list) ding ();
  4122.   else {
  4123.     while (rl_undo_list)
  4124.       rl_do_undo ();
  4125.   }
  4126. }
  4127.  
  4128. /* Do some undoing of things that were done. */
  4129. void rl_undo_command (int count, int dum2)
  4130. {
  4131.   if (count < 0) return;    /* Nothing to do. */
  4132.  
  4133.   while (count)
  4134.     {
  4135.       if (rl_do_undo ())
  4136.     {
  4137.       count--;
  4138.     }
  4139.       else
  4140.     {
  4141.       ding ();
  4142.       break;
  4143.     }
  4144.     }
  4145. }
  4146.  
  4147. /* **************************************************************** */
  4148. /*                                    */
  4149. /*            History Utilities                */
  4150. /*                                    */
  4151. /* **************************************************************** */
  4152.  
  4153. /* We already have a history library, and that is what we use to control
  4154.    the history features of readline.  However, this is our local interface
  4155.    to the history mechanism. */
  4156.  
  4157. /* While we are editing the history, this is the saved
  4158.    version of the original line. */
  4159. static HIST_ENTRY *saved_line_for_history = (HIST_ENTRY *)NULL;
  4160.  
  4161. /* Set the history pointer back to the last entry in the history. */
  4162. static void start_using_history (void)
  4163. {
  4164.   hl_using_history ();
  4165.   if (saved_line_for_history)
  4166.     free_history_entry (saved_line_for_history);
  4167.  
  4168.   saved_line_for_history = (HIST_ENTRY *)NULL;
  4169. }
  4170.  
  4171. /* Free the contents (and containing structure) of a HIST_ENTRY. */
  4172. static void free_history_entry (HIST_ENTRY *entry)
  4173. {
  4174.   if (!entry) return;
  4175.   if (entry->line)
  4176.     free (entry->line);
  4177.   free (entry);
  4178. }
  4179.  
  4180. /* Perhaps put back the current line if it has changed. */
  4181. /* If the current line has changed, save the changes. */
  4182. #define maybe_replace_line()
  4183. /***********************************
  4184. THIS IS MORE A BUG THAN A FEATURE ...
  4185. static void maybe_replace_line (void)
  4186. {
  4187.   HIST_ENTRY *temp = hl_current_history ();
  4188.  
  4189.   if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list)) {
  4190.     temp = hl_replace_history_entry (hl_where_history (),
  4191.     the_line, (char *)rl_undo_list);
  4192.     free (temp->line);
  4193.     free (temp);
  4194.   }
  4195. }
  4196. *************************************/
  4197.  
  4198.  
  4199. /* Put back the saved_line_for_history if there is one. */
  4200. static void maybe_unsave_line (void)
  4201. {
  4202.   if (saved_line_for_history) {
  4203.     strcpy (the_line, saved_line_for_history->line);
  4204.     rl_undo_list = (UNDO_LIST *)saved_line_for_history->data;
  4205.     free_history_entry (saved_line_for_history);
  4206.     saved_line_for_history = (HIST_ENTRY *)NULL;
  4207.     rl_end = rl_point = strlen (the_line);
  4208.   } else {
  4209.     ding ();
  4210.   }
  4211. }
  4212.  
  4213. /* Save the current line in saved_line_for_history. */
  4214. static void maybe_save_line (void)
  4215. {
  4216.   if (!saved_line_for_history) {
  4217.     saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
  4218.     saved_line_for_history->line = savestring (the_line);
  4219.     saved_line_for_history->data = (char *)rl_undo_list;
  4220.   }
  4221. }
  4222.  
  4223.  
  4224. /* **************************************************************** */
  4225. /*                                    */
  4226. /*            History Commands                */
  4227. /*                                    */
  4228. /* **************************************************************** */
  4229.  
  4230. /* Meta-< goes to the start of the history. */
  4231. void rl_beginning_of_history (int dum1, int dum2)
  4232. {
  4233.   rl_get_previous_history (1 + hl_where_history (), 0);
  4234. }
  4235.  
  4236. /* Meta-> goes to the end of the history.  (The current line). */
  4237. void rl_end_of_history (int dum1, int dum2)
  4238. {
  4239.   maybe_replace_line ();
  4240.   hl_using_history ();
  4241.   maybe_unsave_line ();
  4242. }
  4243.  
  4244. /* Move down to the next history line. */
  4245. void rl_get_next_history (int count, int dum2)
  4246. {
  4247.   HIST_ENTRY *temp = (HIST_ENTRY *)NULL;
  4248.  
  4249.   if (count < 0)
  4250.     {
  4251.       rl_get_previous_history (-count, 0);
  4252.       return;
  4253.     }
  4254.  
  4255.   if (!count)
  4256.     return;
  4257.  
  4258.   maybe_replace_line ();
  4259.  
  4260.   while (count)
  4261.     {
  4262.       temp = hl_next_history ();
  4263.       if (!temp)
  4264.     break;
  4265.       --count;
  4266.     }
  4267.  
  4268.   if (!temp)
  4269.     maybe_unsave_line ();
  4270.   else
  4271.     {
  4272.       strcpy (the_line, temp->line);
  4273.       rl_undo_list = (UNDO_LIST *)temp->data;
  4274.       rl_end = rl_point = strlen (the_line);
  4275.     }
  4276. }
  4277.  
  4278. /* Get the previous item out of our interactive history, making it the current
  4279.    line.  If there is no previous history, just ding. */
  4280. void rl_get_previous_history (int count, int dum2)
  4281. {
  4282.   HIST_ENTRY *old_temp = (HIST_ENTRY *)NULL;
  4283.   HIST_ENTRY *temp = (HIST_ENTRY *)NULL;
  4284.  
  4285.   if (count < 0)
  4286.     {
  4287.       rl_get_next_history (-count, 0);
  4288.       return;
  4289.     }
  4290.  
  4291.   if (!count)
  4292.     return;
  4293.  
  4294.   /* If we don't have a line saved, then save this one. */
  4295.   maybe_save_line ();
  4296.  
  4297.   /* If the current line has changed, save the changes. */
  4298.   maybe_replace_line ();
  4299.  
  4300.   while (count)
  4301.     {
  4302.       temp = hl_previous_history ();
  4303.       if (!temp)
  4304.     break;
  4305.       else
  4306.     old_temp = temp;
  4307.       --count;
  4308.     }
  4309.  
  4310.   /* If there was a large argument, and we moved back to the start of the
  4311.      history, that is not an error.  So use the last value found. */
  4312.   if (!temp && old_temp)
  4313.     temp = old_temp;
  4314.  
  4315.   if (!temp)
  4316.     ding ();
  4317.   else
  4318.     {
  4319.       strcpy (the_line, temp->line);
  4320.       rl_undo_list = (UNDO_LIST *)temp->data;
  4321.       rl_end = rl_point = strlen (the_line);
  4322. #ifdef VI_MODE
  4323.       if (rl_editing_mode == vi_mode)
  4324.     rl_point = 0;
  4325. #endif /* VI_MODE */
  4326.     }
  4327. }
  4328.  
  4329. /* There is a command in the K*rn shell which yanks into this line, the last
  4330.    word of the previous line.  Here it is.  We left it on M-. */
  4331. void rl_yank_previous_last_arg (int ignore, int dum2)
  4332. {
  4333. }
  4334.  
  4335.  
  4336. /* **************************************************************** */
  4337. /*                                    */
  4338. /*            I-Search and Searching                */
  4339. /*                                    */
  4340. /* **************************************************************** */
  4341.  
  4342. /* Search backwards through the history looking for a string which is typed
  4343.    interactively.  Start with the current line. */
  4344. void rl_reverse_search_history (int sign, int key)
  4345. {
  4346.   rl_search_history (-sign, key);
  4347. }
  4348.  
  4349. /* Search forwards through the history looking for a string which is typed
  4350.    interactively.  Start with the current line. */
  4351. void rl_forward_search_history (int sign, int key)
  4352. {
  4353.   rl_search_history (sign, key);
  4354. }
  4355.  
  4356. /* Display the current state of the search in the echo-area.
  4357.    SEARCH_STRING contains the string that is being searched for,
  4358.    DIRECTION is zero for forward, or 1 for reverse,
  4359.    WHERE is the history list number of the current line.  If it is
  4360.    -1, then this line is the starting one. */
  4361. void rl_display_search (char *search_string, int reverse_p, int where)
  4362. {
  4363.   char *message = (char *)NULL;
  4364.  
  4365.   message =
  4366.     (char *)alloca (1 + (search_string ? strlen (search_string) : 0) + 30);
  4367.  
  4368.   *message = '\0';
  4369.  
  4370. #ifdef NEVER
  4371.   if (where != -1)
  4372.     sprintf (message, "[%d]", where + history_base);
  4373. #endif
  4374.  
  4375.   strcat (message, "(");
  4376.  
  4377.   if (reverse_p)
  4378.     strcat (message, "reverse-");
  4379.  
  4380.   strcat (message, "i-search)`");
  4381.  
  4382.   if (search_string)
  4383.     strcat (message, search_string);
  4384.  
  4385.   strcat (message, "': ");
  4386.   rl_message (message, 0, 0);
  4387.   rl_redisplay ();
  4388. }
  4389.  
  4390. /* Search through the history looking for an interactively typed string.
  4391.    This is analogous to i-search.  We start the search in the current line.
  4392.    DIRECTION is which direction to search; > 0 means forward, < 0 means
  4393.    backwards. */
  4394. void rl_search_history (int direction, int invoking_key)
  4395. {
  4396.   /* The string that the user types in to search for. */
  4397.   char *search_string = (char *)alloca (128);
  4398.  
  4399.   /* The current length of SEARCH_STRING. */
  4400.   int search_string_index;
  4401.  
  4402.   /* The list of lines to search through. */
  4403.   char **lines;
  4404.  
  4405.   /* The length of LINES. */
  4406.   int hlen;
  4407.  
  4408.   /* Where we get LINES from. */
  4409.   HIST_ENTRY **hlist = hl_history_list ();
  4410.  
  4411.   register int i = 0;
  4412.   int orig_point = rl_point;
  4413.   int orig_line = hl_where_history ();
  4414.   int last_found_line = orig_line;
  4415.   int c, done = 0;
  4416.  
  4417.   /* The line currently being searched. */
  4418.   char *sline;
  4419.  
  4420.   /* Offset in that line. */
  4421.   int hindex;
  4422.  
  4423.   /* Non-zero if we are doing a reverse search. */
  4424.   int reverse = (direction < 0);
  4425.  
  4426.   /* Create an arrary of pointers to the lines that we want to search. */
  4427.   maybe_replace_line ();
  4428.   if (hlist)
  4429.     for (i = 0; hlist[i]; i++)
  4430.         ;
  4431.  
  4432.   /* Allocate space for this many lines, +1 for the current input line,
  4433.      and remember those lines. */
  4434.   lines = (char **)alloca ((1 + (hlen = i)) * sizeof (char *));
  4435.   for (i = 0; i < hlen; i++)
  4436.     lines[i] = hlist[i]->line;
  4437.  
  4438.   if (saved_line_for_history)
  4439.     lines[i] = saved_line_for_history->line;
  4440.   else
  4441.     {
  4442.       char *cp;
  4443.       /* So I have to type it in this way instead. */
  4444.       cp = (char *)alloca (1 + strlen (the_line));
  4445.       lines[i] = cp;
  4446.       strcpy (lines[i], &the_line[0]);
  4447.     }
  4448.  
  4449.   hlen++;
  4450.  
  4451.   /* The line where we start the search. */
  4452.   i = orig_line;
  4453.  
  4454.   /* Initialize search parameters. */
  4455.   *search_string = '\0';
  4456.   search_string_index = 0;
  4457.  
  4458.   rl_display_search (search_string, reverse, -1);
  4459.  
  4460.   sline = the_line;
  4461.   hindex = rl_point;
  4462.  
  4463.   while (!done)
  4464.     {
  4465.       c = rl_read_key ();
  4466.  
  4467.       /* Hack C to Do What I Mean. */
  4468.       {
  4469.     KFunction *f = (KFunction *)NULL;
  4470.  
  4471.     if (keymap[c].type == ISFUNC)
  4472.       f = keymap[c].function;
  4473.  
  4474.     if (f == rl_reverse_search_history)
  4475.       c = reverse ? -1 : -2;
  4476.     else if (f == rl_forward_search_history)
  4477.       c =  !reverse ? -1 : -2;
  4478.       }
  4479.  
  4480.       switch (c)
  4481.     {
  4482.     case ESC:
  4483.       done = 1;
  4484.       continue;
  4485.  
  4486.       /* case invoking_key: */
  4487.     case -1:
  4488.       goto search_again;
  4489.  
  4490.       /* switch directions */
  4491.     case -2:
  4492.       direction = -direction;
  4493.       reverse = (direction < 0);
  4494.  
  4495.       goto do_search;
  4496.  
  4497.     case CTRL ('G'):
  4498.       strcpy (the_line, lines[orig_line]);
  4499.       rl_point = orig_point;
  4500.       rl_end = strlen (the_line);
  4501.       rl_clear_message ();
  4502.       return;
  4503.  
  4504.     default:
  4505.       if (c < 32 || c > 126)
  4506.         {
  4507.           rl_execute_next (c);
  4508.           done = 1;
  4509.           continue;
  4510.         }
  4511.       else
  4512.         {
  4513.           search_string[search_string_index++] = c;
  4514.           search_string[search_string_index] = '\0';
  4515.           goto do_search;
  4516.  
  4517.         search_again:
  4518.  
  4519.           if (!search_string_index)
  4520.         continue;
  4521.           else
  4522.         {
  4523.           if (reverse)
  4524.             --hindex;
  4525.           else
  4526.             if (hindex != strlen (sline))
  4527.               ++hindex;
  4528.             else
  4529.               ding ();
  4530.         }
  4531.         do_search:
  4532.  
  4533.           while (1)
  4534.         {
  4535.           if (reverse)
  4536.             {
  4537.               while (hindex >= 0)
  4538.             if (strncmp
  4539.                 (search_string,
  4540.                  sline + hindex,
  4541.                  search_string_index) == 0)
  4542.               goto string_found;
  4543.             else
  4544.               hindex--;
  4545.             }
  4546.           else
  4547.             {
  4548.               register int limit =
  4549.             (strlen (sline) - search_string_index) + 1;
  4550.  
  4551.               while (hindex < limit)
  4552.             {
  4553.               if (strncmp (search_string,
  4554.                        sline + hindex,
  4555.                        search_string_index) == 0)
  4556.                 goto string_found;
  4557.               hindex++;
  4558.             }
  4559.             }
  4560.  
  4561.         next_line:
  4562.           i += direction;
  4563.  
  4564.           /* At limit for direction? */
  4565.           if ((reverse && i < 0) ||
  4566.               (!reverse && i == hlen))
  4567.             goto search_failed;
  4568.  
  4569.           sline = lines[i];
  4570.           if (reverse)
  4571.             hindex = strlen (sline);
  4572.           else
  4573.             hindex = 0;
  4574.  
  4575.           /* If the search string is longer than the current
  4576.              line, no match. */
  4577.           if (search_string_index > strlen (sline))
  4578.             goto next_line;
  4579.  
  4580.           /* Start actually searching. */
  4581.           if (reverse)
  4582.             hindex -= search_string_index;
  4583.         }
  4584.  
  4585.         search_failed:
  4586.           /* We cannot find the search string.  Ding the bell. */
  4587.           ding ();
  4588.           i = last_found_line;
  4589.           break;
  4590.  
  4591.         string_found:
  4592.           /* We have found the search string.  Just display it.  But don't
  4593.          actually move there in the history list until the user accepts
  4594.          the location. */
  4595.           strcpy (the_line, lines[i]);
  4596.           rl_point = hindex;
  4597.           rl_end = strlen (the_line);
  4598.           last_found_line = i;
  4599.           rl_display_search (search_string, reverse,
  4600.                  (i == orig_line) ? -1 : i);
  4601.         }
  4602.     }
  4603.       continue;
  4604.     }
  4605.  
  4606.   /* The searching is over.  The user may have found the string that she
  4607.      was looking for, or else she may have exited a failing search.  If
  4608.      INDEX is -1, then that shows that the string searched for was not
  4609.      found.  We use this to determine where to place rl_point. */
  4610.   {
  4611.     int now = last_found_line;
  4612.  
  4613.     /* First put back the original state. */
  4614.     strcpy (the_line, lines[orig_line]);
  4615.  
  4616.     if (now < orig_line)
  4617.       rl_get_previous_history (orig_line - now, 0);
  4618.     else
  4619.       rl_get_next_history (now - orig_line, 0);
  4620.  
  4621.     /* If the index of the "matched" string is less than zero, then the
  4622.        final search string was never matched, so put point somewhere
  4623.        reasonable. */
  4624.     if (hindex < 0)
  4625.       hindex = strlen (the_line);
  4626.  
  4627.     rl_point = hindex;
  4628.     rl_clear_message ();
  4629.   }
  4630. }
  4631.  
  4632. /* Make C be the next command to be executed. */
  4633. void rl_execute_next (int c)
  4634. {
  4635.   rl_pending_input = c;
  4636. }
  4637.  
  4638. /* **************************************************************** */
  4639. /*                                    */
  4640. /*            Killing Mechanism                */
  4641. /*                                    */
  4642. /* **************************************************************** */
  4643.  
  4644. /* What we assume for a max number of kills. */
  4645. #define DEFAULT_MAX_KILLS 10
  4646.  
  4647. /* The real variable to look at to find out when to flush kills. */
  4648. int rl_max_kills = DEFAULT_MAX_KILLS;
  4649.  
  4650. /* Where to store killed text. */
  4651. char **rl_kill_ring = (char **)NULL;
  4652.  
  4653. /* Where we are in the kill ring. */
  4654. int rl_kill_index = 0;
  4655.  
  4656. /* How many slots we have in the kill ring. */
  4657. int rl_kill_ring_length = 0;
  4658.  
  4659. /* How to say that you only want to save a certain amount
  4660.    of kill material. */
  4661. void rl_set_retained_kills (int num)
  4662. {
  4663.     rl_max_kills = num;
  4664. }
  4665.  
  4666. /* The way to kill something.  This appends or prepends to the last
  4667.    kill, if the last command was a kill command.  if FROM is less
  4668.    than TO, then the text is appended, otherwise prepended.  If the
  4669.    last command was not a kill command, then a new slot is made for
  4670.    this kill. */
  4671. void rl_kill_text (int from, int to)
  4672. {
  4673.   int slot;
  4674.   char *text = rl_copy (from, to);
  4675.  
  4676.   /* Is there anything to kill? */
  4677.   if (from == to) {
  4678.       free (text);
  4679.       last_command_was_kill++;
  4680.       return;
  4681.   }
  4682.  
  4683.   /* Delete the copied text from the line. */
  4684.   rl_delete_text (from, to);
  4685.  
  4686.   /* First, find the slot to work with. */
  4687.   if (!last_command_was_kill) {
  4688.       /* Get a new slot.  */
  4689.       if (!rl_kill_ring) {
  4690.         /* If we don't have any defined, then make one. */
  4691.         rl_kill_ring = (char **)
  4692.         xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
  4693.         slot = 1;
  4694.       }
  4695.       else {
  4696.       /* We have to add a new slot on the end, unless we have
  4697.          exceeded the max limit for remembering kills. */
  4698.         slot = rl_kill_ring_length;
  4699.         if (slot == rl_max_kills) {
  4700.           register int i;
  4701.           free (rl_kill_ring[0]);
  4702.           for (i = 0; i < slot; i++)
  4703.             rl_kill_ring[i] = rl_kill_ring[i + 1];
  4704.         }
  4705.         else {
  4706.           rl_kill_ring = (char **) xrealloc (rl_kill_ring,
  4707.         ((slot = (rl_kill_ring_length += 1)) + 1) * sizeof(char *));
  4708.         }
  4709.      }
  4710.      slot--;
  4711.   }
  4712.   else {
  4713.      slot = rl_kill_ring_length - 1;
  4714.   }
  4715.  
  4716.   /* If the last command was a kill, prepend or append. */
  4717.   if (last_command_was_kill && rl_editing_mode != vi_mode) {
  4718.       char *old = rl_kill_ring[slot];
  4719.       char *new = (char *)xmalloc (1 + strlen (old) + strlen (text));
  4720.  
  4721.       if (from < to) {
  4722.          strcpy (new, old);
  4723.          strcat (new, text);
  4724.       }
  4725.       else {
  4726.         strcpy (new, text);
  4727.         strcat (new, old);
  4728.       }
  4729.       free (old);
  4730.       free (text);
  4731.       rl_kill_ring[slot] = new;
  4732.   }
  4733.   else {
  4734.       rl_kill_ring[slot] = text;
  4735.   }
  4736.   rl_kill_index = slot;
  4737.   last_command_was_kill++;
  4738. }
  4739.  
  4740. /* Now REMEMBER!  In order to do prepending or appending correctly, kill
  4741.    commands always make rl_point's original position be the FROM argument,
  4742.    and rl_point's extent be the TO argument. */
  4743.  
  4744. /* **************************************************************** */
  4745. /*                                    */
  4746. /*            Killing Commands                */
  4747. /*                                    */
  4748. /* **************************************************************** */
  4749.  
  4750. /* Delete the word at point, saving the text in the kill ring. */
  4751. void rl_kill_word (int count, int dum2)
  4752. {
  4753.   int orig_point = rl_point;
  4754.  
  4755.   if (count < 0)
  4756.     rl_backward_kill_word (-count, 0);
  4757.   else
  4758.     {
  4759.       rl_forward_word (count, 0);
  4760.  
  4761.       if (rl_point != orig_point)
  4762.     rl_kill_text (orig_point, rl_point);
  4763.  
  4764.       rl_point = orig_point;
  4765.     }
  4766. }
  4767.  
  4768. /* Rubout the word before point, placing it on the kill ring. */
  4769. void rl_backward_kill_word (int count, int dum2)
  4770. {
  4771.   int orig_point = rl_point;
  4772.  
  4773.   if (count < 0)
  4774.     rl_kill_word (-count, 0);
  4775.   else
  4776.     {
  4777.       rl_backward_word (count, 0);
  4778.  
  4779.       if (rl_point != orig_point)
  4780.     rl_kill_text (orig_point, rl_point);
  4781.     }
  4782. }
  4783.  
  4784. /* Kill from here to the end of the line.  If DIRECTION is negative, kill
  4785.    back to the line start instead. */
  4786. void rl_kill_line (int direction, int dum2)
  4787. {
  4788.   int orig_point = rl_point;
  4789.  
  4790.   if (direction < 0)
  4791.     rl_backward_kill_line (1, 0);
  4792.   else
  4793.     {
  4794.       rl_end_of_line (0, 0);
  4795.       if (orig_point != rl_point)
  4796.     rl_kill_text (orig_point, rl_point);
  4797.       rl_point = orig_point;
  4798.     }
  4799. }
  4800.  
  4801. /* Kill backwards to the start of the line.  If DIRECTION is negative, kill
  4802.    forwards to the line end instead. */
  4803. void rl_backward_kill_line (int direction, int dum2)
  4804. {
  4805.   int orig_point = rl_point;
  4806.  
  4807.   if (direction < 0)
  4808.     rl_kill_line (1, 0);
  4809.   else
  4810.     {
  4811.       if (!rl_point)
  4812.     ding ();
  4813.       else
  4814.     {
  4815.       rl_beg_of_line (0, 0);
  4816.       rl_kill_text (orig_point, rl_point);
  4817.     }
  4818.     }
  4819. }
  4820.  
  4821. /* Yank back the last killed text.  This ignores arguments. */
  4822. void rl_yank (int dum1, int dum2)
  4823. {
  4824.   if (!rl_kill_ring) rl_abort (0, 0);
  4825.   rl_insert_text (rl_kill_ring[rl_kill_index]);
  4826. }
  4827.  
  4828. /* If the last command was yank, or yank_pop, and the text just
  4829.    before point is identical to the current kill item, then
  4830.    delete that text from the line, rotate the index down, and
  4831.    yank back some other text. */
  4832. void rl_yank_pop (int dum1, int dum2)
  4833. {
  4834.   int l;
  4835.  
  4836.   if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
  4837.       !rl_kill_ring)
  4838.     {
  4839.       rl_abort (0, 0);
  4840.     }
  4841.  
  4842.   l = strlen (rl_kill_ring[rl_kill_index]);
  4843.   if (((rl_point - l) >= 0) &&
  4844.       (strncmp (the_line + (rl_point - l),
  4845.         rl_kill_ring[rl_kill_index], l) == 0))
  4846.     {
  4847.       rl_delete_text ((rl_point - l), rl_point);
  4848.       rl_point -= l;
  4849.       rl_kill_index--;
  4850.       if (rl_kill_index < 0)
  4851.     rl_kill_index = rl_kill_ring_length - 1;
  4852.       rl_yank (0, 0);
  4853.     }
  4854.   else
  4855.     rl_abort (0, 0);
  4856.  
  4857. }
  4858.  
  4859. /* Yank the COUNTth argument from the previous history line. */
  4860. void rl_yank_nth_arg (int count, int ignore)
  4861. {
  4862.   register HIST_ENTRY *entry = hl_previous_history ();
  4863.   char *arg;
  4864.  
  4865.   if (entry)
  4866.     hl_next_history ();
  4867.   else
  4868.     {
  4869.       ding ();
  4870.       return;
  4871.     }
  4872.  
  4873.   arg = hl_history_arg_extract (count, count, entry->line);
  4874.   if (!arg || !*arg)
  4875.     {
  4876.       ding ();
  4877.       return;
  4878.     }
  4879.  
  4880.   rl_begin_undo_group ();
  4881.   if (rl_point && the_line[rl_point - 1] != ' ')
  4882.     rl_insert_text (" ");
  4883.   rl_insert_text (arg);
  4884.   free (arg);
  4885.   rl_end_undo_group ();
  4886. }
  4887.  
  4888. /* Vi Mode. */
  4889. #ifdef VI_MODE
  4890. #include "vi_mode.c"
  4891. #endif /* VI_MODE */
  4892.  
  4893. /* How to toggle back and forth between editing modes. */
  4894. void rl_vi_editing_mode (int dum1, int dum2)
  4895. {
  4896. #ifdef VI_MODE
  4897.   rl_editing_mode = vi_mode;
  4898.   rl_vi_insertion_mode (0, 0);
  4899. #endif /* VI_MODE */
  4900. }
  4901.  
  4902. void rl_emacs_editing_mode (int dum1, int dum2)
  4903. {
  4904.   rl_editing_mode = emacs_mode;
  4905.   keymap = emacs_standard_keymap;
  4906. }
  4907.  
  4908.  
  4909. /* **************************************************************** */
  4910. /*                                    */
  4911. /*                 Completion                    */
  4912. /*                                    */
  4913. /* **************************************************************** */
  4914.  
  4915. /* Non-zero means that case is not significant in completion. */
  4916. int completion_case_fold = 0;
  4917.  
  4918. /* Return an array of (char *) which is a list of completions for TEXT.
  4919.    If there are no completions, return a NULL pointer.
  4920.    The first entry in the returned array is the substitution for TEXT.
  4921.     The remaining entries are the possible completions.
  4922.    The array is terminated with a NULL pointer.
  4923.  
  4924.    ENTRY_FUNCTION is a function of two args, and returns a (char *).
  4925.      The first argument is TEXT.
  4926.      The second is a state argument; it should be zero on the first call, and
  4927.      non-zero on subsequent calls.  It returns a NULL pointer to the caller
  4928.      when there are no more matches.
  4929.  */
  4930. char **
  4931. completion_matches (char *text, CFunction *entry_function)
  4932. {
  4933.   /* Number of slots in match_list. */
  4934.   int match_list_size;
  4935.  
  4936.   /* The list of matches. */
  4937.   char **match_list =
  4938.     (char **)xmalloc (((match_list_size = 10) + 1) * sizeof (char *));
  4939.  
  4940.   /* Number of matches actually found. */
  4941.   int matches = 0;
  4942.  
  4943.   /* Temporary string binder. */
  4944.   char *string;
  4945.  
  4946.   match_list[1] = (char *)NULL;
  4947.  
  4948.   while (string = (*entry_function) (text, matches))
  4949.     {
  4950.       if (matches + 1 == match_list_size)
  4951.     match_list =
  4952.       (char **)xrealloc (match_list,
  4953.                  ((match_list_size += 10) + 1) * sizeof(char *));
  4954.  
  4955.       match_list[++matches] = string;
  4956.       match_list[matches + 1] = (char *)NULL;
  4957.     }
  4958.  
  4959.   /* If there were any matches, then look through them finding out the
  4960.      lowest common denominator.  That then becomes match_list[0]. */
  4961.   if (matches)
  4962.     {
  4963.       register int i = 1;
  4964.       int low = 100000;        /* Count of max-matched characters. */
  4965.  
  4966.       /* If only one match, just use that. */
  4967.       if (matches == 1)
  4968.     {
  4969.       match_list[0] = match_list[1];
  4970.       match_list[1] = (char *)NULL;
  4971.     }
  4972.       else
  4973.     {
  4974.       /* Otherwise, compare each member of the list with
  4975.          the next, finding out where they stop matching. */
  4976.  
  4977.       while (i < matches)
  4978.         {
  4979.           register int c1, c2, si;
  4980.  
  4981.           if (completion_case_fold)
  4982.         {
  4983.           for (si = 0;
  4984.                (c1 = to_lower(match_list[i][si])) &&
  4985.                (c2 = to_lower(match_list[i + 1][si]));
  4986.                si++)
  4987.             if (c1 != c2) break;
  4988.         }
  4989.           else
  4990.         {
  4991.           for (si = 0;
  4992.                (c1 = match_list[i][si]) &&
  4993.                (c2 = match_list[i + 1][si]);
  4994.                si++)
  4995.             if (c1 != c2) break;
  4996.         }
  4997.  
  4998.           if (low > si) low = si;
  4999.           i++;
  5000.         }
  5001.       match_list[0] = (char *)xmalloc (low + 1);
  5002.       strncpy (match_list[0], match_list[1], low);
  5003.       match_list[0][low] = '\0';
  5004.     }
  5005.     }
  5006.   else                /* There were no matches. */
  5007.     {
  5008.       free (match_list);
  5009.       match_list = (char **)NULL;
  5010.     }
  5011.   return (match_list);
  5012. }
  5013.  
  5014. /* Okay, now we write the entry_function for filename completion.  In the
  5015.    general case.  Note that completion in the shell is a little different
  5016.    because of all the pathnames that must be followed when looking up the
  5017.    completion for a command. */
  5018. static char *
  5019. filename_completion_function (char *text, int state, int dummy)
  5020. {
  5021.   static DIR *directory;
  5022.   static char *filename = (char *)NULL;
  5023.   static char *dirname = (char *)NULL;
  5024.   static char *users_dirname = (char *)NULL;
  5025.   static int filename_len;
  5026.  
  5027.   struct direct *entry = (struct direct *)NULL;
  5028.  
  5029.   /* If we don't have any state, then do some initialization. */
  5030.   if (!state)
  5031.     {
  5032.       char *temp;
  5033.  
  5034.       if (dirname) free (dirname);
  5035.       if (filename) free (filename);
  5036.       if (users_dirname) free (users_dirname);
  5037.  
  5038.       filename = savestring (text);
  5039.       if (!*text) text = ".";
  5040.       dirname = savestring (text);
  5041.  
  5042.       temp = strrchr (dirname, '/');
  5043.  
  5044.       if (temp)
  5045.     {
  5046.       strcpy (filename, ++temp);
  5047.       *temp = '\0';
  5048.     }
  5049.       else
  5050.     strcpy (dirname, ".");
  5051.  
  5052.       /* We aren't done yet.  We also support the "~user" syntax. */
  5053.  
  5054.       /* Save the version of the directory that the user typed. */
  5055.       users_dirname = savestring (dirname);
  5056.       {
  5057.     char *temp_dirname = tilde_expand (dirname);
  5058.  
  5059.     free (dirname);
  5060.     dirname = temp_dirname;
  5061.  
  5062.     if (rl_symbolic_link_hook)
  5063.       (*rl_symbolic_link_hook) (&dirname);
  5064.       }
  5065.       directory = opendir (dirname);
  5066.       filename_len = strlen (filename);
  5067.  
  5068.       rl_filename_completion_desired = 1;
  5069.     }
  5070.  
  5071.   /* At this point we should entertain the possibility of hacking wildcarded
  5072.      filenames, like /usr/man*\/te<TAB>.  If the directory name contains
  5073.      globbing characters, then build an array of directories to glob on, and
  5074.      glob on the first one. */
  5075.  
  5076.   /* Now that we have some state, we can read the directory. */
  5077.  
  5078.   while (directory && (entry = readdir (directory)))
  5079.     {
  5080.       /* Special case for no filename.
  5081.      All entries except "." and ".." match. */
  5082.       if (!filename_len)
  5083.     {
  5084.       if ((strcmp (entry->d_name, ".") != 0) &&
  5085.           (strcmp (entry->d_name, "..") != 0))
  5086.         break;
  5087.     }
  5088.       else
  5089.     {
  5090.       /* Otherwise, if these match upto the length of filename, then
  5091.          it is a match. */
  5092.         if ((entry->d_namlen >= filename_len) &&
  5093.         (strncmp (filename, entry->d_name, filename_len) == 0))
  5094.           {
  5095.         break;
  5096.           }
  5097.     }
  5098.     }
  5099.  
  5100.   if (!entry)
  5101.     {
  5102.       if (directory)
  5103.     {
  5104.       closedir (directory);
  5105.       directory = (DIR *)NULL;
  5106.     }
  5107.       return (char *)NULL;
  5108.     }
  5109.   else
  5110.     {
  5111.       char *temp;
  5112.  
  5113.       if (dirname && (strcmp (dirname, ".") != 0))
  5114.     {
  5115.       temp = (char *)xmalloc (1 + strlen (users_dirname)
  5116.                   + entry->d_namlen);
  5117.       strcpy (temp, users_dirname);
  5118.       strcat (temp, entry->d_name);
  5119.     }
  5120.       else
  5121.     {
  5122.       temp = (savestring (entry->d_name));
  5123.     }
  5124.       return (temp);
  5125.     }
  5126. }
  5127.  
  5128.  
  5129. /* **************************************************************** */
  5130. /*                                    */
  5131. /*            Binding keys                    */
  5132. /*                                    */
  5133. /* **************************************************************** */
  5134.  
  5135. /* rl_add_defun (char *name, Function *function, int key)
  5136.    Add NAME to the list of named functions.  Make FUNCTION
  5137.    be the function that gets called.
  5138.    If KEY is not -1, then bind it. */
  5139. void rl_add_defun (char *name, KFunction (*function), int key)
  5140. {
  5141.   if (key != -1)
  5142.     rl_bind_key (key, function);
  5143.   rl_add_funmap_entry (name, function);
  5144. }
  5145.  
  5146. /* Bind KEY to FUNCTION.  Returns non-zero if KEY is out of range. */
  5147. int
  5148. rl_bind_key (int key, KFunction (*function))
  5149. {
  5150.   if (key < 0)
  5151.     return (key);
  5152.  
  5153.   if (key > 127 && key < 256)
  5154.     {
  5155.       if (keymap[ESC].type == ISKMAP)
  5156.     {
  5157.       Keymap escmap = (Keymap)keymap[ESC].function;
  5158.  
  5159.       key -= 128;
  5160.       escmap[key].type = ISFUNC;
  5161.       escmap[key].function = function;
  5162.       return (0);
  5163.     }
  5164.       return (key);
  5165.     }
  5166.  
  5167.   keymap[key].type = ISFUNC;
  5168.   keymap[key].function = function;
  5169.  return (0);
  5170. }
  5171.  
  5172. /* Bind KEY to FUNCTION in MAP.  Returns non-zero in case of invalid
  5173.    KEY. */
  5174. int
  5175. rl_bind_key_in_map (int key, KFunction (*function), Keymap map)
  5176. {
  5177.   int result;
  5178.   Keymap oldmap = keymap;
  5179.  
  5180.   keymap = map;
  5181.   result = rl_bind_key (key, function);
  5182.   keymap = oldmap;
  5183.   return (result);
  5184. }
  5185.  
  5186. /* Make KEY do nothing in the currently selected keymap.
  5187.    Returns non-zero in case of error. */
  5188. int
  5189. rl_unbind_key (int key)
  5190. {
  5191.   return (rl_bind_key (key, (KFunction *)NULL));
  5192. }
  5193.  
  5194. /* Make KEY do nothing in MAP.
  5195.    Returns non-zero in case of error. */
  5196. int
  5197. rl_unbind_key_in_map (int key, Keymap map)
  5198. {
  5199.   return (rl_bind_key_in_map (key, (KFunction *)NULL, map));
  5200. }
  5201.  
  5202. /* Bind the key sequence represented by the string KEYSEQ to
  5203.    FUNCTION.  This makes new keymaps as necessary.  The initial
  5204.    place to do bindings is in MAP. */
  5205. void rl_set_key (char *keyseq, KFunction (*function), Keymap map)
  5206. {
  5207.   rl_generic_bind (ISFUNC, keyseq, (char *)function, map);
  5208. }
  5209.  
  5210. /* Bind the key sequence represented by the string KEYSEQ to
  5211.    the string of characters MACRO.  This makes new keymaps as
  5212.    necessary.  The initial place to do bindings is in MAP. */
  5213. void rl_macro_bind (char *keyseq, char *macro, Keymap map)
  5214. {
  5215.   char *macro_keys = (char *)xmalloc (2 * (strlen (macro)));
  5216.   int macro_keys_len;
  5217.  
  5218.   if (rl_translate_keyseq (macro, macro_keys, ¯o_keys_len))
  5219.     {
  5220.       free (macro_keys);
  5221.       return;
  5222.     }
  5223.   rl_generic_bind (ISMACR, keyseq, macro_keys, map);
  5224. }
  5225.  
  5226. /* Bind the key sequence represented by the string KEYSEQ to
  5227.    the arbitrary pointer DATA.  TYPE says what kind of data is
  5228.    pointed to by DATA, right now this can be a function (ISFUNC),
  5229.    a macro (ISMACR), or a keymap (ISKMAP).  This makes new keymaps
  5230.    as necessary.  The initial place to do bindings is in MAP. */
  5231. void rl_generic_bind (int type, char *keyseq, char *data, Keymap map)
  5232. {
  5233.   char *keys;
  5234.   int keys_len;
  5235.   register int i;
  5236.  
  5237.   /* If no keys to bind to, exit right away. */
  5238.   if (!keyseq || !*keyseq)
  5239.     {
  5240.       if (type == ISMACR)
  5241.     free (data);
  5242.       return;
  5243.     }
  5244.  
  5245.   keys = (char *)alloca (1 + (2 * strlen (keyseq)));
  5246.  
  5247.   /* Translate the ASCII representation of KEYSEQ into an array
  5248.      of characters.  Stuff the characters into ARRAY, and the
  5249.      length of ARRAY into LENGTH. */
  5250.   if (rl_translate_keyseq (keyseq, keys, &keys_len))
  5251.     return;
  5252.  
  5253.   /* Bind keys, making new keymaps as necessary. */
  5254.   for (i = 0; i < keys_len; i++)
  5255.     {
  5256.       if (i + 1 < keys_len)
  5257.     {
  5258.       if (map[keys[i]].type != ISKMAP)
  5259.         {
  5260.           if (map[i].type == ISMACR)
  5261.         free ((char *)map[i].function);
  5262.  
  5263.           map[keys[i]].type = ISKMAP;
  5264.           map[keys[i]].function = (KFunction *)rl_make_bare_keymap ();
  5265.         }
  5266.       map = (Keymap)map[keys[i]].function;
  5267.     }
  5268.       else
  5269.     {
  5270.       if (map[keys[i]].type == ISMACR)
  5271.         free ((char *)map[keys[i]].function);
  5272.  
  5273.       map[keys[i]].function = (KFunction *)data;
  5274.       map[keys[i]].type = type;
  5275.     }
  5276.     }
  5277. }
  5278.  
  5279. /* Translate the ASCII representation of SEQ, stuffing the
  5280.    values into ARRAY, an array of characters.  LEN gets the
  5281.    final length of ARRAY.  Return non-zero if there was an
  5282.    error parsing SEQ. */
  5283. int rl_translate_keyseq (char *seq, char *array, int *len)
  5284. {
  5285.   register int i, c, l = 0;
  5286.  
  5287.   for (i = 0; c = seq[i]; i++)
  5288.     {
  5289.       if (c == '\\')
  5290.     {
  5291.       c = seq[++i];
  5292.  
  5293.       if (!c)
  5294.         break;
  5295.  
  5296.       if (((c == 'C' || c == 'M') &&  seq[i + 1] == '-') ||
  5297.           (c == 'e'))
  5298.         {
  5299.           /* Handle special case of backwards define. */
  5300.           if (strncmp (&seq[i], "C-\\M-", 5) == 0)
  5301.         {
  5302.           array[l++] = ESC;
  5303.           i += 5;
  5304.           array[l++] = CTRL (to_upper (seq[i]));
  5305.           if (!seq[i])
  5306.             i--;
  5307.           continue;
  5308.         }
  5309.  
  5310.           switch (c)
  5311.         {
  5312.         case 'M':
  5313.           i++;
  5314.           array[l++] = ESC;
  5315.           break;
  5316.  
  5317.         case 'C':
  5318.           i += 2;
  5319.           array[l++] = CTRL (to_upper (seq[i]));
  5320.           break;
  5321.  
  5322.         case 'e':
  5323.           array[l++] = ESC;
  5324.         }
  5325.  
  5326.           continue;
  5327.         }
  5328.     }
  5329.       array[l++] = c;
  5330.     }
  5331.  
  5332.   *len = l;
  5333.   array[l] = '\0';
  5334.   return (0);
  5335. }
  5336.  
  5337. /* Return a pointer to the function that STRING represents.
  5338.    If STRING doesn't have a matching function, then a NULL pointer
  5339.    is returned. */
  5340. KFunction *
  5341. rl_named_function (char *string)
  5342. {
  5343.   register int i;
  5344.  
  5345.   for (i = 0; funmap[i]; i++)
  5346.     if (stricmp (funmap[i]->name, string) == 0)
  5347.       return (funmap[i]->function);
  5348.   return ((KFunction *)NULL);
  5349. }
  5350.  
  5351. /* The last key bindings file read. */
  5352. static char *last_readline_init_file = "~/.inputrc";
  5353.  
  5354. /* Re-read the current keybindings file. */
  5355. void rl_re_read_init_file (int count, int ignore)
  5356. {
  5357.   rl_read_init_file ((char *)NULL);
  5358. }
  5359.  
  5360. /* Do key bindings from a file.  If FILENAME is NULL it defaults
  5361.    to `~/.inputrc'.  If the file existed and could be opened and
  5362.    read, 0 is returned, otherwise errno is returned. */
  5363. int
  5364. rl_read_init_file (char *filename)
  5365. {
  5366.   register int i;
  5367.   char *buffer, *openname, *line, *end;
  5368.   struct stat finfo;
  5369.   int file;
  5370.  
  5371.   /* Default the filename. */
  5372.   if (!filename)
  5373.     filename = last_readline_init_file;
  5374.  
  5375.   openname = tilde_expand (filename);
  5376.  
  5377.   if ((stat (openname, &finfo) < 0) ||
  5378.       (file = open (openname, O_RDONLY, 0666)) < 0)
  5379.     {
  5380.       free (openname);
  5381.       return (errno);
  5382.     }
  5383.   else
  5384.     free (openname);
  5385.  
  5386.   last_readline_init_file = filename;
  5387.  
  5388.   /* Read the file into BUFFER. */
  5389.   buffer = (char *)xmalloc (finfo.st_size + 1);
  5390.   i = read (file, buffer, finfo.st_size);
  5391.   close (file);
  5392.  
  5393.   if (i != finfo.st_size)
  5394.     return (errno);
  5395.  
  5396.   /* Loop over the lines in the file.  Lines that start with `#' are
  5397.      comments; all other lines are commands for readline initialization. */
  5398.   line = buffer;
  5399.   end = buffer + finfo.st_size;
  5400.   while (line < end)
  5401.     {
  5402.       /* Find the end of this line. */
  5403.       for (i = 0; line + i != end && line[i] != '\n'; i++)
  5404.         ;
  5405.  
  5406.       /* Mark end of line. */
  5407.       line[i] = '\0';
  5408.  
  5409.       /* If the line is not a comment, then parse it. */
  5410.       if (*line != '#')
  5411.     rl_parse_and_bind (line);
  5412.  
  5413.       /* Move to the next line. */
  5414.       line += i + 1;
  5415.     }
  5416.   return (0);
  5417. }
  5418.  
  5419. /* **************************************************************** */
  5420. /*                                    */
  5421. /*            Parser Directives                   */
  5422. /*                                    */
  5423. /* **************************************************************** */
  5424.  
  5425. /* Conditionals. */
  5426.  
  5427. /* Calling programs set this to have their argv[0]. */
  5428. char *rl_readline_name = "other";
  5429.  
  5430. /* Stack of previous values of parsing_conditionalized_out. */
  5431. static unsigned char *if_stack = (unsigned char *)NULL;
  5432. static int if_stack_depth = 0;
  5433. static int if_stack_size = 0;
  5434.  
  5435. /* Push parsing_conditionalized_out, and set parser state based on ARGS. */
  5436. void parser_if (char *args)
  5437. {
  5438.   register int i;
  5439.  
  5440.   /* Push parser state. */
  5441.   if (if_stack_depth + 1 >= if_stack_size)
  5442.     {
  5443.       if (!if_stack)
  5444.     if_stack = (unsigned char *)xmalloc (if_stack_size = 20);
  5445.       else
  5446.     if_stack = (unsigned char *)xrealloc (if_stack,
  5447.     if_stack_size += 20);
  5448.     }
  5449.   if_stack[if_stack_depth++] = parsing_conditionalized_out;
  5450.  
  5451.   /* We only check to see if the first word in ARGS is the same as the
  5452.      value stored in rl_readline_name. */
  5453.  
  5454.   /* Isolate first argument. */
  5455.   for (i = 0; args[i] && !whitespace (args[i]); i++)
  5456.     ;
  5457.  
  5458.   if (args[i])
  5459.     args[i++] = '\0';
  5460.  
  5461.   /* Handle "if term=foo" construct.  If this isn't term=foo, then
  5462.      check to see if the first word in ARGS is the same as the
  5463.      value stored in rl_readline_name. */
  5464.   if (rl_terminal_name && strnicmp (args, "term=", 5) == 0)
  5465.     {
  5466.       char *tem, *tname;
  5467.  
  5468.       /* Terminals like "aaa-60" are equivalent to "aaa". */
  5469.       tname = savestring (rl_terminal_name);
  5470.       tem = strrchr (tname, '-');
  5471.       if (tem)
  5472.     *tem = '\0';
  5473.  
  5474.       if (stricmp (args + 5, tname) == 0)
  5475.     parsing_conditionalized_out = 1;
  5476.       else
  5477.     parsing_conditionalized_out = 0;
  5478.     }
  5479.   else if (stricmp (args, rl_readline_name) == 0)
  5480.     parsing_conditionalized_out = 0;
  5481.   else
  5482.     parsing_conditionalized_out = 1;
  5483. }
  5484.  
  5485. /* Invert the current parser state if there is anything on the stack. */
  5486. void parser_else (char *args)
  5487. {
  5488.   if (if_stack_depth)
  5489.     parsing_conditionalized_out = !parsing_conditionalized_out;
  5490.   else
  5491.     {
  5492.       /* *** What, no error message? *** */
  5493.     }
  5494. }
  5495.  
  5496. /* Terminate a conditional, popping the value of
  5497.    parsing_conditionalized_out from the stack. */
  5498. void parser_endif (char *args)
  5499. {
  5500.   if (if_stack_depth)
  5501.     parsing_conditionalized_out = if_stack[--if_stack_depth];
  5502.   else
  5503.     {
  5504.       /* *** What, no error message? *** */
  5505.     }
  5506. }
  5507.  
  5508. /* Associate textual names with actual functions. */
  5509. static struct {
  5510.   char *name;
  5511.   VFunction *function;
  5512. } parser_directives [] = {
  5513.   { "if", parser_if },
  5514.   { "endif", parser_endif },
  5515.   { "else", parser_else },
  5516.   { (char *)0x0, (VFunction *)0x0 }
  5517. };
  5518.  
  5519. /* Handle a parser directive.  STATEMENT is the line of the directive
  5520.    without any leading `$'. */
  5521. static int
  5522. handle_parser_directive (char *statement)
  5523. {
  5524.   register int i;
  5525.   char *directive, *args;
  5526.  
  5527.   /* Isolate the actual directive. */
  5528.  
  5529.   /* Skip whitespace. */
  5530.   for (i = 0; whitespace (statement[i]); i++)
  5531.     ;
  5532.  
  5533.   directive = &statement[i];
  5534.  
  5535.   for (; statement[i] && !whitespace (statement[i]); i++)
  5536.     ;
  5537.  
  5538.   if (statement[i])
  5539.     statement[i++] = '\0';
  5540.  
  5541.   for (; statement[i] && whitespace (statement[i]); i++)
  5542.     ;
  5543.  
  5544.   args = &statement[i];
  5545.  
  5546.   /* Lookup the command, and act on it. */
  5547.   for (i = 0; parser_directives[i].name; i++)
  5548.     if (stricmp (directive, parser_directives[i].name) == 0)
  5549.       {
  5550.     (*parser_directives[i].function) (args);
  5551.     return (0);
  5552.       }
  5553.  
  5554.   /* *** Should an error message be output? */
  5555.   return (1);
  5556. }
  5557.  
  5558. static int substring_member_of_array (char *string, char **array);
  5559.  
  5560. /* Read the binding command from STRING and perform it.
  5561.    A key binding command looks like: Keyname: function-name\0,
  5562.    a variable binding command looks like: set variable value.
  5563.    A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */
  5564. void rl_parse_and_bind (char *string)
  5565. {
  5566.   extern char *possible_control_prefixes[], *possible_meta_prefixes[];
  5567.   char *funname, *kname;
  5568.   register int c;
  5569.   int key, i;
  5570.  
  5571.   if (!string || !*string || *string == '#')
  5572.     return;
  5573.  
  5574.   /* If this is a parser directive, act on it. */
  5575.   if (*string == '$')
  5576.     {
  5577.       handle_parser_directive (&string[1]);
  5578.       return;
  5579.     }
  5580.  
  5581.   /* If we are supposed to be skipping parsing right now, then do it. */
  5582.   if (parsing_conditionalized_out)
  5583.     return;
  5584.  
  5585.   i = 0;
  5586.   /* If this keyname is a complex key expression surrounded by quotes,
  5587.      advance to after the matching close quote. */
  5588.   if (*string == '"')
  5589.     {
  5590.       for (i = 1; c = string[i]; i++)
  5591.     {
  5592.       if (c == '"' && string[i - 1] != '\\')
  5593.         break;
  5594.     }
  5595.     }
  5596.  
  5597.   /* Advance to the colon (:) or whitespace which separates the two objects. */
  5598.   for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ )
  5599.     ;
  5600.  
  5601.   /* Mark the end of the command (or keyname). */
  5602.   if (string[i])
  5603.     string[i++] = '\0';
  5604.  
  5605.   /* If this is a command to set a variable, then do that. */
  5606.   if (stricmp (string, "set") == 0)
  5607.     {
  5608.       char *var = string + i;
  5609.       char *value;
  5610.  
  5611.       /* Make VAR point to start of variable name. */
  5612.       while (*var && whitespace (*var)) var++;
  5613.  
  5614.       /* Make value point to start of value string. */
  5615.       value = var;
  5616.       while (*value && !whitespace (*value)) value++;
  5617.       if (*value)
  5618.     *value++ = '\0';
  5619.       while (*value && whitespace (*value)) value++;
  5620.  
  5621.       rl_variable_bind (var, value);
  5622.       return;
  5623.     }
  5624.  
  5625.   /* Skip any whitespace between keyname and funname. */
  5626.   for (; string[i] && whitespace (string[i]); i++)
  5627.     ;
  5628.   funname = &string[i];
  5629.  
  5630.   /* Now isolate funname.
  5631.      For straight function names just look for whitespace, since
  5632.      that will signify the end of the string.  But this could be a
  5633.      macro definition.  In that case, the string is quoted, so skip
  5634.      to the matching delimiter. */
  5635.   if (*funname == '\'' || *funname == '"')
  5636.     {
  5637.       int delimiter = string[i++];
  5638.  
  5639.       for (; c = string[i]; i++)
  5640.     {
  5641.       if (c == delimiter && string[i - 1] != '\\')
  5642.         break;
  5643.     }
  5644.       if (c)
  5645.     i++;
  5646.     }
  5647.  
  5648.   /* Advance to the end of the string.  */
  5649.   for (; string[i] && !whitespace (string[i]); i++)
  5650.     ;
  5651.  
  5652.   /* No extra whitespace at the end of the string. */
  5653.   string[i] = '\0';
  5654.  
  5655.   /* If this is a new-style key-binding, then do the binding with
  5656.      rl_set_key ().  Otherwise, let the older code deal with it. */
  5657.   if (*string == '"')
  5658.     {
  5659.       char *seq = (char *)alloca (1 + strlen (string));
  5660.       register int j, k = 0;
  5661.  
  5662.       for (j = 1; string[j]; j++)
  5663.     {
  5664.       if (string[j] == '"' && string[j - 1] != '\\')
  5665.         break;
  5666.  
  5667.       seq[k++] = string[j];
  5668.     }
  5669.       seq[k] = '\0';
  5670.  
  5671.       /* Binding macro? */
  5672.       if (*funname == '\'' || *funname == '"')
  5673.     {
  5674.       j = strlen (funname);
  5675.  
  5676.       if (j && funname[j - 1] == *funname)
  5677.         funname[j - 1] = '\0';
  5678.  
  5679.       rl_macro_bind (seq, &funname[1], keymap);
  5680.     }
  5681.       else
  5682.     rl_set_key (seq, rl_named_function (funname), keymap);
  5683.  
  5684.       return;
  5685.     }
  5686.  
  5687.   /* Get the actual character we want to deal with. */
  5688.   kname = strrchr (string, '-');
  5689.   if (!kname)
  5690.     kname = string;
  5691.   else
  5692.     kname++;
  5693.  
  5694.   key = glean_key_from_name (kname);
  5695.  
  5696.   /* Add in control and meta bits. */
  5697.   if (substring_member_of_array (string, possible_control_prefixes))
  5698.     key = CTRL (to_upper (key));
  5699.  
  5700.   if (substring_member_of_array (string, possible_meta_prefixes))
  5701.     key = META (key);
  5702.  
  5703.   /* Temporary.  Handle old-style keyname with macro-binding. */
  5704.   if (*funname == '\'' || *funname == '"')
  5705.     {
  5706.       char seq[2];
  5707.       int fl = strlen (funname);
  5708.  
  5709.       seq[0] = key; seq[1] = '\0';
  5710.       if (fl && funname[fl - 1] == *funname)
  5711.     funname[fl - 1] = '\0';
  5712.  
  5713.       rl_macro_bind (seq, &funname[1], keymap);
  5714.     }
  5715.   else
  5716.     rl_bind_key (key, rl_named_function (funname));
  5717. }
  5718.  
  5719. void rl_variable_bind (char *name, char *value)
  5720. {
  5721.   if (stricmp (name, "editing-mode") == 0)
  5722.     {
  5723.       if (strnicmp (value, "vi", 2) == 0)
  5724.     {
  5725. #ifdef VI_MODE
  5726.       keymap = vi_insertion_keymap;
  5727.       rl_editing_mode = vi_mode;
  5728. #endif /* VI_MODE */
  5729.     }
  5730.       else if (strnicmp (value, "emacs", 5) == 0)
  5731.     {
  5732.       keymap = emacs_standard_keymap;
  5733.       rl_editing_mode = emacs_mode;
  5734.     }
  5735.     }
  5736.   else if (stricmp (name, "horizontal-scroll-mode") == 0)
  5737.     {
  5738.       if (!*value || stricmp (value, "On") == 0)
  5739.     horizontal_scroll_mode = 1;
  5740.       else
  5741.     horizontal_scroll_mode = 0;
  5742.     }
  5743.   /********* Is this a feature ?
  5744.   else if (stricmp (name, "mark-modified-lines") == 0) {
  5745.       if (!*value || stricmp (value, "On") == 0)
  5746.           mark_modified_lines = 1;
  5747.       else
  5748.           mark_modified_lines = 0;
  5749.   }
  5750.   *****************/
  5751.   else if (stricmp (name, "prefer-visible-bell") == 0)
  5752.     {
  5753.       if (!*value || stricmp (value, "On") == 0)
  5754.         prefer_visible_bell = 1;
  5755.       else
  5756.         prefer_visible_bell = 0;
  5757.     }
  5758. }
  5759.  
  5760. /* Return the character which matches NAME.
  5761.    For example, `Space' returns ' '. */
  5762.  
  5763. typedef struct {
  5764.   char *name;
  5765.   int value;
  5766. } assoc_list;
  5767.  
  5768. assoc_list name_key_alist[] = {
  5769.   { "Space", ' ' },
  5770.   { "SPC", ' ' },
  5771.   { "Rubout", 0x7f },
  5772.   { "DEL", 0x7f },
  5773.   { "Tab", 0x09 },
  5774.   { "Newline", '\n' },
  5775.   { "Return", '\r' },
  5776.   { "RET", '\r' },
  5777.   { "LFD", '\n' },
  5778.   { "Escape", '\033' },
  5779.   { "ESC", '\033' },
  5780.  
  5781.   { (char *)0x0, 0 }
  5782. };
  5783.  
  5784. int
  5785. glean_key_from_name (char *name)
  5786. {
  5787.   register int i;
  5788.  
  5789.   for (i = 0; name_key_alist[i].name; i++)
  5790.     if (stricmp (name, name_key_alist[i].name) == 0)
  5791.       return (name_key_alist[i].value);
  5792.  
  5793.   return (*name);
  5794. }
  5795.  
  5796.  
  5797. /* **************************************************************** */
  5798. /*                                    */
  5799. /*            String Utility Functions            */
  5800. /*                                    */
  5801. /* **************************************************************** */
  5802.  
  5803. static char *strindex (register char *s1, register char *s2);
  5804.  
  5805. /* Return non-zero if any members of ARRAY are a substring in STRING. */
  5806. static int
  5807. substring_member_of_array (char *string, char **array)
  5808. {
  5809.   while (*array)
  5810.     {
  5811.       if (strindex (string, *array))
  5812.     return (1);
  5813.       array++;
  5814.     }
  5815.   return (0);
  5816. }
  5817.  
  5818. /* Whoops, Unix doesn't have strnicmp. */
  5819.  
  5820. /* Compare at most COUNT characters from string1 to string2.  Case
  5821.    doesn't matter. */
  5822. static int
  5823. strnicmp (char *string1, char *string2, int count)
  5824. {
  5825.   register char ch1, ch2;
  5826.  
  5827.   while (count)
  5828.     {
  5829.       ch1 = *string1++;
  5830.       ch2 = *string2++;
  5831.       if (to_upper(ch1) == to_upper(ch2))
  5832.     count--;
  5833.       else break;
  5834.     }
  5835.   return (count);
  5836. }
  5837.  
  5838. /* strcmp (), but caseless. */
  5839. static int
  5840. stricmp (char *string1, char *string2)
  5841. {
  5842.   register char ch1, ch2;
  5843.  
  5844.   while (*string1 && *string2)
  5845.     {
  5846.       ch1 = *string1++;
  5847.       ch2 = *string2++;
  5848.       if (to_upper(ch1) != to_upper(ch2))
  5849.     return (1);
  5850.     }
  5851.   return (*string1 | *string2);
  5852. }
  5853.  
  5854. /* Determine if s2 occurs in s1.  If so, return a pointer to the
  5855.    match in s1.  The compare is case insensitive. */
  5856. static char *
  5857. strindex (register char *s1, register char *s2)
  5858. {
  5859.   register int i, l = strlen (s2);
  5860.   register int len = strlen (s1);
  5861.  
  5862.   for (i = 0; (len - i) >= l; i++)
  5863.     if (strnicmp (&s1[i], s2, l) == 0)
  5864.       return (s1 + i);
  5865.   return ((char *)NULL);
  5866. }
  5867.  
  5868.  
  5869. /* **************************************************************** */
  5870. /*                                    */
  5871. /*            USG (System V) Support                */
  5872. /*                                    */
  5873. /* **************************************************************** */
  5874.  
  5875. /* When compiling and running in the `Posix' environment, Ultrix does
  5876.    not restart system calls, so this needs to do it. */
  5877. int
  5878. rl_getc (FILE *stream)
  5879. {
  5880.   int result;
  5881.   unsigned char c;
  5882.  
  5883.   while (1)
  5884.     {
  5885.       result = read (fileno (stream), &c, sizeof (char));
  5886.  
  5887.       if (result == sizeof (char))
  5888.     return (c);
  5889.  
  5890.       if (errno != EINTR)
  5891.     return (EOF);
  5892.     }
  5893. }
  5894.  
  5895. #ifdef STATIC_MALLOC
  5896.  
  5897. /* **************************************************************** */
  5898. /*                                    */
  5899. /*            xmalloc and xrealloc ()                     */
  5900. /*                                    */
  5901. /* **************************************************************** */
  5902.  
  5903. static void memory_error_and_abort (void);
  5904.  
  5905. static char *
  5906. xmalloc (int bytes)
  5907. {
  5908.   char *temp = (char *)malloc (bytes);
  5909.  
  5910.   if (!temp)
  5911.     memory_error_and_abort ();
  5912.   return (temp);
  5913. }
  5914.  
  5915. static char *
  5916. xrealloc (void *pointer, int bytes)
  5917. {
  5918.   char *temp = (char *)realloc (pointer, bytes);
  5919.  
  5920.   if (!temp)
  5921.     memory_error_and_abort ();
  5922.   return (temp);
  5923. }
  5924.  
  5925. static void
  5926. memory_error_and_abort (void)
  5927. {
  5928.   fprintf (stderr, "readline: Out of virtual memory!\n");
  5929.   abort ();
  5930. }
  5931. #endif /* STATIC_MALLOC */
  5932.  
  5933.  
  5934. /* **************************************************************** */
  5935. /*                                    */
  5936. /*            Testing Readline                */
  5937. /*                                    */
  5938. /* **************************************************************** */
  5939.  
  5940. #if defined (TEST)
  5941.  
  5942. main ()
  5943. {
  5944.   extern HIST_ENTRY **hl_history_list (void);
  5945. #ifdef AMIGA
  5946.   rl_instream = stdin; *rl_outstream = stdout;
  5947. #endif
  5948.   char *temp = (char *)NULL;
  5949.   char *prompt = "readline% ";
  5950.   int done = 0;
  5951.  
  5952.   while (!done)
  5953.     {
  5954.       temp = rl_readline (prompt);
  5955.  
  5956.       /* Test for EOF. */
  5957.       if (!temp)
  5958.     exit (1);
  5959.  
  5960.       /* If there is anything on the line, print it and remember it. */
  5961.       if (*temp)
  5962.     {
  5963.       fprintf (stderr, "%s\r\n", temp);
  5964.       hl_add_history (temp);
  5965.     }
  5966.  
  5967.       /* Check for `command' that we handle. */
  5968.       if (strcmp (temp, "quit") == 0)
  5969.     done = 1;
  5970.  
  5971.       if (strcmp (temp, "list") == 0) {
  5972.     HIST_ENTRY **list = hl_history_list ();
  5973.     register int i;
  5974.     if (list) {
  5975.       for (i = 0; list[i]; i++) {
  5976.         fprintf (stderr, "%d: %s\r\n", i, list[i]->line);
  5977.         free (list[i]->line);
  5978.       }
  5979.       free (list);
  5980.     }
  5981.       }
  5982.       free (temp);
  5983.     }
  5984. }
  5985.  
  5986. #endif /* TEST */
  5987.  
  5988.  
  5989. /*
  5990.  * Local variables:
  5991.  * compile-command: "gcc -g -traditional -I. -I.. -DTEST -o readline readline.c keymaps.o funmap.o history.o -ltermcap"
  5992.  * end:
  5993.  */
  5994.